<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Infobip</title>
    <description>The latest articles on Forem by Infobip (@infobipdev).</description>
    <link>https://forem.com/infobipdev</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Forganization%2Fprofile_image%2F3862%2F5afaa859-774a-478e-bee7-e6c6181fe231.png</url>
      <title>Forem: Infobip</title>
      <link>https://forem.com/infobipdev</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/infobipdev"/>
    <language>en</language>
    <item>
      <title>You should build an SDK</title>
      <dc:creator>Mike Elsmore</dc:creator>
      <pubDate>Thu, 22 Feb 2024 17:03:45 +0000</pubDate>
      <link>https://forem.com/infobipdev/you-should-build-an-sdk-1a3i</link>
      <guid>https://forem.com/infobipdev/you-should-build-an-sdk-1a3i</guid>
      <description>&lt;p&gt;Over the last little while in my career, I’ve been either involved in building or building SDKs, especially here at Infobip with the huge array of tools we have on offer. And this leads me down a rabbit hole of wondering why organisations don’t build them by default once they reach a certain size if they follow an API-first design approach.&lt;/p&gt;

&lt;p&gt;I’ve actually given talks on this subject a few times, if you want to skip reading, you can watch the last recording at &lt;iframe width="710" height="399" src="https://www.youtube.com/embed/FM30Z1uPq2E"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  What is an SDK?
&lt;/h2&gt;

&lt;p&gt;Let’s cover the basics: what is an SDK? The acronym itself means Software Development Kit, so it’s a toolkit for developing software. According to Wikipedia, the definition of an SDK is&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A software development kit (SDK) is a collection of software development tools in one installable package. They facilitate the creation of applications by having a compiler, debugger and sometimes a software framework. They are normally specific to a hardware platform and operating system combination. To create applications with advanced functionalities such as advertisements, push notifications, etc; most application software developers use specific software development kits.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://en.wikipedia.org/wiki/Software_development_kit" rel="noopener noreferrer"&gt;https://en.wikipedia.org/wiki/Software_development_kit&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This means that I, and many like me who have treated SDKs as whatever the package manager installs, are a bit wrong (not totally, just a bit).  What I mean by this, is that Client Libraries, like those that wrap an HTTP API, are not the SDK but a part of an SDK. An SDK is a collection of tools; this can include your client libraries, but also other dev tools. It could include testing tooling, webhook definitions, or even mathematical models for doing a task. Those of us who build primarily for the web or for mobile applications forget that they can also be physical SDKs. Game developers working on next-gen hardware regularly get access to kits like these for the PS5&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fawueeyyxicq4ghn9uz8h.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fawueeyyxicq4ghn9uz8h.png" alt="PlayStation 5 Development Kit" width="620" height="375"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;At Infobip, we have a lot of SDKs, you can check them out here on &lt;a href="https://www.infobip.com/developers/sdks" rel="noopener noreferrer"&gt;our SDK page&lt;/a&gt;, but what I’ve been calling our NodeJS SDK is just a client library for now.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why bother building an SDK?
&lt;/h2&gt;

&lt;p&gt;Most people I know who are building SDKs are trying to enable a developer outside of their organisation, be it open source or proprietary, to consume the tools and products being built. I think this is wrong, and for a very simple reason, internal &amp;amp; external developers deserve the same tools.&lt;/p&gt;

&lt;p&gt;Yes, external developers need help and ease of onboarding or use to engage with technology. But so do internal developers, it’s not uncommon for organisations to be running different services, with different technologies, and differing knowledge or experience levels.&lt;/p&gt;

&lt;p&gt;Say the organisation you are in has some “legacy” systems running that no one actively works on but are used to grab information or tools that have been brought in over years and never updated. An internal client library providing a consistent set of functions to use them, as well as ETL tooling to make sure older standards are converted to the currently used ones, is a great SDK to build internally and manage. Or you could have REST, GraphQL, and WSDL systems that don’t have specification files or complete documentation on how to handle everything. A well-made SDK could solve that for teams.&lt;/p&gt;

&lt;p&gt;Essentially, for internal and external developers, an SDK can lower the learning curve, which leads to speeding up implementation and provides consistency across everything being built.&lt;/p&gt;

&lt;h2&gt;
  
  
  How can you build one?
&lt;/h2&gt;

&lt;p&gt;SDKs are meant to make life easier for the person using them, so the advice around developing them is rather straightforward.&lt;/p&gt;

&lt;p&gt;If you are developing a wrapper library or code to be used or to be imported and used in a code base, follow the instructions and best practices for the languages or frameworks it’s being developed for. For example, if you’re creating it for the Express framework in NodeJS then you’ll need to follow the middleware pattern that it requires.&lt;/p&gt;

&lt;p&gt;Where possible, use a namespace structure to allow people to only include the parts of the SDK they require if they do not need to use the whole thing. For example, &lt;a href="https://fastify.dev/" rel="noopener noreferrer"&gt;fastify&lt;/a&gt; is a web framework in NodeJS and only the core structure needed for routing and requests are within the main fastify module. For everything else, that is expected of a full nuts and bolts framework, they’re included as an ecosystem of &lt;code&gt;@fastify&lt;/code&gt; modules, like so &lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5c29h9n71adp77nbz90l.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5c29h9n71adp77nbz90l.png" alt="The complete list of Fastify modules that make up the frameworks" width="800" height="976"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you are developing a client library, follow a standard. Don’t hop about code styles, etc., as it’ll defeat the point of being easy to consume. And whenever you have to break the standard, make it known. Most languages and development environments allow you to easily see things like &lt;a href="https://en.wikipedia.org/wiki/Docblock" rel="noopener noreferrer"&gt;DocBlocks&lt;/a&gt; to explain why and also how to consume this edge case.&lt;/p&gt;

&lt;p&gt;Let’s move on to something controversial among my peers. Personally, I think it is totally OK to use generators to produce client libraries. If you’re using standards like the OpenAPI Specification, you can use a plethora of generators to produce the first version of your client library codebase. And most importantly, where it isn’t fit for your purposes, you can modify the template, or completely extend the generator to give you the library you want. I definitely endorse this practice, as it’s something we do here at Infobip.&lt;/p&gt;

&lt;p&gt;And now for some best practice tips, just to make everyone’s life a little easier to maintain them. Use version control on the code base that’s in-line with the language it’s been developed in. Additionally, where possible, use dependency management tooling and static analysis tools to make the maintenance and security risks manageable.&lt;/p&gt;

</description>
      <category>sdk</category>
      <category>devex</category>
      <category>api</category>
      <category>development</category>
    </item>
    <item>
      <title>Write a URL Shortener in 26 Lines of Code with .NET Minimal APIs</title>
      <dc:creator>Dino Lozina</dc:creator>
      <pubDate>Thu, 13 Jan 2022 13:16:45 +0000</pubDate>
      <link>https://forem.com/infobipdev/write-a-url-shortener-in-26-lines-of-code-with-net-minimal-apis-2k0k</link>
      <guid>https://forem.com/infobipdev/write-a-url-shortener-in-26-lines-of-code-with-net-minimal-apis-2k0k</guid>
      <description>&lt;p&gt;I was looking forward to .NET minimal API framework for a very long time and now, it is finally out! Let’s dive into new version of .NET6 and answer the following questions:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;What is .NET minimal API?&lt;/li&gt;
&lt;li&gt;How to refactor existing URL shortener?&lt;/li&gt;
&lt;li&gt;How to add dependency to service?&lt;/li&gt;
&lt;li&gt;How to add endpoint to service?&lt;/li&gt;
&lt;li&gt;Where are using statements?&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  🤔 1. Introducing .NET Minimal APIs
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;”Do you need all of this stuff just to shorten URL?”&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;This was a first reaction of a friend (who happens to be a Python programmer) when I showed him my &lt;a href="https://github.com/dlozina/url-shortener-service-v2"&gt;first shortner example&lt;/a&gt;. "Yes" would have been a pretty accurate answer, but not the one that I’d be happy with.&lt;/p&gt;

&lt;p&gt;There was a lot of boilerplate code compared to other frameworks.&lt;br&gt;
One benefit is that the structure is already set up — very convenient when we have larger projects to tackle. On the other hand, not ideal when I need to create a small service as part of a microservices architecture. &lt;br&gt;
Most SaaS providers are using microservice architecture for its scalability,smaller/faster deployments, and ease of understanding.&lt;/p&gt;

&lt;p&gt;Take a look at the Flask API template:&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;In just 5 lines of code, we have our first endpoint! Single file, no other setup needed. All we need to focus on is the feature of this new service.&lt;/p&gt;

&lt;p&gt;Now, let’s take a look at the .NET template. Out of the box we get &lt;em&gt;Startup.cs&lt;/em&gt;, &lt;em&gt;Program.cs&lt;/em&gt;, &lt;em&gt;Controllers&lt;/em&gt;…a lot of boilerplate code. This could be unnecessary if the goal is to write one small service as part of a SaaS product or just a prototype.  &lt;/p&gt;

&lt;p&gt;Fortunately, .NET6 addresses this issue. Let's rewrite the previous example in &lt;strong&gt;.NET6 with a new template&lt;/strong&gt;.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;4 lines of code for our first endpoint and a single file. This is new .NET minimal API!&lt;/p&gt;

&lt;p&gt;Back to my friend’s question - &lt;em&gt;“Do you need all of this stuff just to shorten URL?”&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;No.&lt;br&gt;
I can do better.&lt;/p&gt;
&lt;h3&gt;
  
  
  ✂️ 2. Refactored URL shortener example
&lt;/h3&gt;

&lt;p&gt;A while back, I wrote a post on &lt;a href="https://dev.to/infobipdev/how-to-write-url-shortener-in-net5-weve-made-it-seem-easy-1-5c56"&gt;how to create a URL shortener in .NET5&lt;/a&gt;), but I never imagined that I'd be able to rewrite it in 26 lines of code and a single file.&lt;/p&gt;

&lt;p&gt;*&lt;em&gt;Note: we actually have two files—we will get to the bottom of that in the fifth section, bear with me.&lt;/em&gt; &lt;/p&gt;

&lt;p&gt;Refactored code:&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;You can find the previous URL shortener example in this &lt;a href="https://github.com/dlozina/url-shortener-service-v2"&gt;github repository&lt;/a&gt;. There is nothing minimal about the codebase.&lt;br&gt;&lt;br&gt;
If we compare the old code to our minimal shortener, we will see the hidden complexity of the minimal API framework right away.&lt;/p&gt;

&lt;p&gt;We start from scratch in the minimal API template and only introduce the dependencies we need. We can concentrate on the important stuff—the code for the requested feature.   &lt;/p&gt;

&lt;p&gt;Let's analyse the code and see what new things come with .NET6 that you could start implementing in your services.&lt;/p&gt;
&lt;h3&gt;
  
  
  ⚙️ 3. Adding Dependencies
&lt;/h3&gt;

&lt;p&gt;My service needs database, so I'm adding a dependency to LiteDB.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;dotnet add package LiteDB
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Usually, we would go to Startup.cs and set up our dependency. Since we don’t have one, the way to go is shown below on line 2. Same code, different position.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;h3&gt;
  
  
  🔗 4. Adding an Endpoint
&lt;/h3&gt;

&lt;p&gt;All the methods we need are in the app—or should I say framework?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;MapGet(pattern, handler)&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;MapPost(pattern, handler)&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;MapPut(pattern, handler)&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;MapDelete(pattern, handler)&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Check how to implement &lt;code&gt;POST&lt;/code&gt; method and &lt;code&gt;GET&lt;/code&gt; method in the example below.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;The first parameter is route pattern, the second parameter is handler. The handler is delegate executed when endpoint is matched.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;The &lt;code&gt;Url&lt;/code&gt; object is &lt;code&gt;record&lt;/code&gt;, also something new in .NET6. It could be a class as well, but I just wanted to shred couple of lines of code to get those 26 magic lines.&lt;/p&gt;

&lt;p&gt;Data that our &lt;code&gt;POST&lt;/code&gt; method (body of req) needs to contain is&lt;br&gt;
defined by the &lt;code&gt;record&lt;/code&gt;. (It is enough to send &lt;code&gt;longURL&lt;/code&gt;, &lt;code&gt;id&lt;/code&gt; will be set automatically by our &lt;code&gt;db&lt;/code&gt;)&lt;/p&gt;

&lt;p&gt;We have our database in the list of services that our app uses. The next step is to inject it into the endpoint. The delegate needs to have our database context to add data from the client to the database.&lt;/p&gt;

&lt;p&gt;In the end, set up your service address and port.&lt;br&gt;
And you are done!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;app.Run("http://localhost:4000");
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  🙋 5. Where are using statements?
&lt;/h3&gt;

&lt;p&gt;Global using statements is another feature I am happy with. Do you remember something like this on top of every file in your project?&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using System;
using System.Reflection;
using System.Linq;
using System.Net.Http;
using System.Linq;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Implicit usings are hidden in auto generated file inside your &lt;em&gt;obj&lt;/em&gt; folder. That file declares global &lt;code&gt;using&lt;/code&gt; statements behind the scenes. If you go to project folder then go &lt;em&gt;obj/Debug/net6.0&lt;/em&gt;, you will find a file titled &lt;em&gt;“{ProjectName}.GlobalUsings.g.cs”&lt;/em&gt;. &lt;/p&gt;

&lt;p&gt;Open this file, and see the content:&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;p&gt;Since this is an autogenerated file, we can’t edit it here. &lt;br&gt;
In our minimal shortener we have two packages (LiteDB, Hashids.net) that we depend upon, and we will actually need to place &lt;code&gt;using&lt;/code&gt; statements in our &lt;em&gt;Program.cs&lt;/em&gt; to use code from packages.&lt;/p&gt;

&lt;p&gt;Instead, let's manually create a file that will hold our global &lt;code&gt;using&lt;/code&gt; statements. This way, we keep our &lt;em&gt;Program.cs&lt;/em&gt; free from all using statements.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;It might be overkill in this particular example, but imagine adding more dependencies. It is a good option for keeping code clean.&lt;/p&gt;

&lt;h3&gt;
  
  
  🎊 So, is it possible? Of course! 🎊
&lt;/h3&gt;

&lt;p&gt;Most of the time, we don’t need all the ceremony that we got with previous .NET webapi templates. &lt;/p&gt;

&lt;p&gt;Now we have the option to start from scratch and add only stuff that we really need. Missing MVC Controllers? No problem.Add them later. Need Authentication? Same thing.&lt;/p&gt;

&lt;p&gt;The template code has fewer files and a more intuitive setup for newcomers in the .NET world—this is probably one of the best benefits of this framework. I am really looking forward to seeing what future updates bring along.  &lt;/p&gt;

&lt;p&gt;If you enjoyed following along and building your own URL shortener in .NET6, keep an eye out for this blog!&lt;br&gt;
In the next article, we will place this minimal URL Shortener in Docker and explore another essential piece of the tech stack.&lt;/p&gt;

</description>
      <category>dotnet</category>
      <category>csharp</category>
      <category>webdev</category>
      <category>programming</category>
    </item>
    <item>
      <title>Passwordless SMS Authentication 101 | Python Edition</title>
      <dc:creator>aldin</dc:creator>
      <pubDate>Fri, 19 Nov 2021 17:32:16 +0000</pubDate>
      <link>https://forem.com/infobipdev/passwordless-sms-authentication-101-python-edition-2b8p</link>
      <guid>https://forem.com/infobipdev/passwordless-sms-authentication-101-python-edition-2b8p</guid>
      <description>&lt;p&gt;Imagine yourself logging into an application without being required to create and remember a password. Well, not much to imagine, right? We all did it at least once before. There are plenty of approaches on how to implement this. One of those approaches is also by using passwordless SMS authentication. &lt;/p&gt;

&lt;h2&gt;
  
  
  What is Passwordless SMS Authentication?
&lt;/h2&gt;

&lt;p&gt;Passwordless SMS Authentication enables application developers to offer authentication without having to remember login credentials. It allows users to enter their mobile device phone number to get a one-time code which can help them to log in.&lt;/p&gt;

&lt;p&gt;With this user authentication technique, when, for example, a mobile user authenticates in an app for the first time, they are asked for their phone number. A one-time code is then sent from the developer's server-side app to that phone number as an SMS text message. The user then enters the code into the app and they are authenticated.&lt;/p&gt;

&lt;p&gt;Let's say it's the first time for a user to use the app. An account will be created for that user. If not, the user will be authenticated to use the unique ID assigned by the identity provider. The authentication code sent to the user's phone number is not reusable, but it can only be used once, after which it expires. When the user visits the app again, a new code will be sent to their mobile phone number, which they can use to log in.&lt;/p&gt;

&lt;p&gt;Thus, it will either:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt; save your users from the need to remember account passwords, or&lt;/li&gt;
&lt;li&gt;add another level of security in case you want to use it as an add-on in the 2FA, 3FA, or MFA setup.
There are suitable use-cases for either approach.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  When (not) to use it?
&lt;/h2&gt;

&lt;p&gt;So, when and why should you use (or avoid) this mode of authentication?&lt;/p&gt;

&lt;p&gt;I guess the answer to this question varies depending on what are you trying to achieve. There are more elegant ways and which significantly reduce the risk of fraudulent activities such as account takeover, and there are enough articles out there talking about how and why should you go with either alternative approach.&lt;/p&gt;

&lt;p&gt;To keep it completely real, if you are seeking ultimate security, you might consider using SMS simply as one of the layers of your multi-factor authentication process. Or you might just say: nope, I want something else.&lt;/p&gt;

&lt;p&gt;If you're simply trying to do a simple integration that enables you to verify your user's phone number or really anything that is not that safety-critical, then sure, jump on board - it's easy to do it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fn61o7qfibp2iff6ryt54.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fn61o7qfibp2iff6ryt54.png" alt="Infobip Phone Verification" width="800" height="265"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ok, by now you should kind of be aware of what it is, and what might be the benefits or potential pitfalls. I guess it is safe to proceed with a bit of hands-on and see how this actually works in practice.&lt;/p&gt;

&lt;h2&gt;
  
  
  Passwordless SMS Authentication in Python
&lt;/h2&gt;

&lt;p&gt;In this section, we will be discussing one approach on how to implement this authentication technique.&lt;/p&gt;

&lt;p&gt;Infobip platform offers you a solution that you can use to send authentication messages. It provides official API libraries for different (at the moment of writing: Java, C#, PHP, Python &amp;amp; Go) programming languages. &lt;/p&gt;

&lt;p&gt;You can find the list of various SDKs provided by this platform &lt;a href="https://www.infobip.com/docs/sdk" rel="noopener noreferrer"&gt;here&lt;/a&gt;. All our API-related SDKs are open-source and made available on &lt;a href="https://github.com/infobip?q=infobip-api-*-client&amp;amp;type=&amp;amp;language=&amp;amp;sort=" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;. To learn more about the platform, visit its &lt;a href="https://www.infobip.com/docs/api" rel="noopener noreferrer"&gt;official documentation here&lt;/a&gt;. In this section, we will be demonstrating how to use the Infobip Python API library to send one-time passwords via SMS.&lt;/p&gt;

&lt;h3&gt;
  
  
  Package installation
&lt;/h3&gt;

&lt;p&gt;First, you should install the &lt;code&gt;infobip-api-python-client&lt;/code&gt;. You can install it using Python's pip package manager. Pip is shipped with Python, thus, you don't have to install it if you have already installed Python.&lt;/p&gt;

&lt;p&gt;Open the terminal of your operating system and run the following command:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;pip install infobip-api-python-client&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The command will install &lt;code&gt;infobip-api-python-client&lt;/code&gt; on your computer. You should get a success message similar to the one shown in the following image.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk53tmi86k2pdusxsbuym.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk53tmi86k2pdusxsbuym.png" alt="Installing Python Package" width="800" height="210"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Configuration
&lt;/h3&gt;

&lt;p&gt;Have you created an Infobip account? If not, please do so &lt;a href="https://www.infobip.com/signup?signup_source=PasswordlessSMSAuthPython101" rel="noopener noreferrer"&gt;here&lt;/a&gt;, you'll need one in order to follow this to the letter. The next step should involve configuration and authentication. To properly set the configuration, you need a specific URL and an API key (both is provided to you when the account is created). You can find both on the &lt;a href="https://portal.infobip.com/" rel="noopener noreferrer"&gt;homepage&lt;/a&gt; of your account.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft9rh4wea7yd85igqshgl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft9rh4wea7yd85igqshgl.png" alt="Portal homepage" width="800" height="129"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To be able to use both of the above, simply click the copy-to-clipboard buttons and paste them into their proper locations in the config setup.&lt;/p&gt;

&lt;p&gt;In order to initialize the Infobip 2FA API client and properly set the configuration for it, you should do the following.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Ensure that you substitute the right values of the various parameters in the above code. These include the API Base URL, the API Key, and the API Key prefix. For you to send the SMS successfully, these credentials MUST be correct.&lt;/p&gt;

&lt;p&gt;While API Base URL and API Key you can simply copy from your account homepage, you have to set API Prefix manually. The reason behind this is that there are multiple authentication options, and you might choose not to use API Key but one of its alternatives. In case you chose to simply copy the key value available on your account, then you need to set the API Key Prefix value to &lt;code&gt;App&lt;/code&gt;. That's it, you are ready to make API calls to the Infobip platform.&lt;/p&gt;

&lt;h3&gt;
  
  
  Application Setup
&lt;/h3&gt;

&lt;p&gt;Before being able to send one-time passwords you need to set up the application and message template. &lt;/p&gt;

&lt;p&gt;The application represents the service you are using it for. It is recommended to have different applications configured for different use cases or services. That is done by invoking the &lt;a href="https://www.infobip.com/docs/api#channels/sms/create-2fa-application" rel="noopener noreferrer"&gt;Create 2FA Application&lt;/a&gt; endpoint.  Python lib you previously installed does it like shown below.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;The last line reads the id of the created application so you can re-use it. Spoiler alert, you need it for the next step.&lt;/p&gt;

&lt;h3&gt;
  
  
  Message Template Setup
&lt;/h3&gt;

&lt;p&gt;When the application is configured, you need to prepare the template for the message(s) you want to send. Let's see an example of how can you design the message body and the password (PIN) placeholder.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Similar to what you did in the previous chapter, now you read the id of the created message template. In order to actually send a password via SMS, we'll need both of the IDs - application and message template.&lt;/p&gt;

&lt;h3&gt;
  
  
  Sending SMS
&lt;/h3&gt;

&lt;p&gt;Now that you have set up the application and designed the message template, let's send the code to the user via SMS. In order to do it, you can simply use the following:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Note that after sending the password you checked whether the message was sent successfully, and also saved another id. This one is going to be used in order to verify the user to whom you sent the SMS message.&lt;/p&gt;

&lt;h3&gt;
  
  
  Authentication Verification
&lt;/h3&gt;

&lt;p&gt;So, you configured everything and sent the password. But how do you know whether the proper password was used by the user?&lt;br&gt;
Well, obviously you somehow have to offer the user a way to put the password you just sent to him. After he does it, you simply need to call the following and check whether the response says the user is verified.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;And if &lt;code&gt;verified&lt;/code&gt; is &lt;code&gt;true&lt;/code&gt;, that's it -your user successfully authenticated himself.&lt;/p&gt;

&lt;h2&gt;
  
  
  To conclude
&lt;/h2&gt;

&lt;p&gt;Passwordless SMS Authentication can be used in various cases. Where needed, it can help developers to authenticate users without requiring them to remember a password. In other cases, it can be used to provide an additional layer of security on top of the basic username-password authentication. &lt;/p&gt;

&lt;p&gt;It's really up to the application owner(s) to determine whether they need extra simplicity or extra security. This article is not going to go there,  its sole purpose is to show you how easy it is to set it up.&lt;/p&gt;

&lt;p&gt;Today we covered how it can be done via SMS, but Infobip also allows you to do utilize it via Voice and/or Email as well. Even Biometrics and something called Silent Mobile Verification are in play - more on it in one of the next articles.&lt;/p&gt;

&lt;p&gt;Feel free to check this out and try it yourself after you &lt;a href="https://www.infobip.com/signup?signup_source=PasswordlessSMSAuthPython101" rel="noopener noreferrer"&gt;create a trial account&lt;/a&gt; (needless to say; a free one). Unless you already have one, in which case you simply &lt;a href="https://www.infobip.com/docs/api" rel="noopener noreferrer"&gt;go and play&lt;/a&gt; with it.&lt;/p&gt;

</description>
      <category>passwordless</category>
      <category>python</category>
      <category>2fa</category>
      <category>authentication</category>
    </item>
    <item>
      <title>How to schedule tasks in .NET? We've made it seem easy #2</title>
      <dc:creator>Dino Lozina</dc:creator>
      <pubDate>Thu, 18 Nov 2021 08:25:29 +0000</pubDate>
      <link>https://forem.com/infobipdev/how-to-schedule-tasks-in-net-weve-made-it-seem-easy-2-511n</link>
      <guid>https://forem.com/infobipdev/how-to-schedule-tasks-in-net-weve-made-it-seem-easy-2-511n</guid>
      <description>&lt;p&gt;Welcome to the second part of the series about "URL shortener in .NET". In the first post of this series we created simple URL shortener web service, and tested it manually with Postman. Check &lt;a href="https://dev.to/infobipdev/how-to-write-url-shortener-in-net5-weve-made-it-seem-easy-1-5c56"&gt;part one&lt;/a&gt; here or skip it if you only want to find out how to schedule services in .NET.&lt;/p&gt;

&lt;p&gt;In part two, we want to expand functionality of our web service with some additional features, such as SMS reports.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;This post aims to show you:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;How to send SMS &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;How to easily add scheduler to our web service&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;How to send SMS periodically &lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Use my &lt;a href="https://github.com/dlozina/url-shortener-service-v2"&gt;github&lt;/a&gt; to find a finished project and avoid the nuisance of writing the code yourself.&lt;/p&gt;

&lt;h3&gt;
  
  
  📱 &lt;strong&gt;First Step: Send SMS&lt;/strong&gt; ✔️
&lt;/h3&gt;

&lt;p&gt;For our SMS provider we will use Infobip. Please access our free trial self service account through this &lt;a href="https://www.infobip.com/docs/api"&gt;link&lt;/a&gt;. After grabbing our API key and URL you just need to implement client library in the project. &lt;/p&gt;

&lt;p&gt;Library: (&lt;a href="https://github.com/infobip/infobip-api-csharp-client"&gt;github&lt;/a&gt;)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;dotnet add package Infobip.Api.Client
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Then, place your user settings in &lt;em&gt;appsettings.json&lt;/em&gt;, so that you can easily grab them through our web app.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;p&gt;Based on Infobip library, we will create method SendNotificationSms:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Let's go through &lt;code&gt;SendNotificationSms(string smsNotificationMessage)&lt;/code&gt;. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;First, we set up the configuration we will send to &lt;code&gt;SendSmsApi&lt;/code&gt; class.&lt;/li&gt;
&lt;li&gt;Then create &lt;code&gt;SmsTextualMessage&lt;/code&gt; by setting up Form, Destination and Text fields.&lt;/li&gt;
&lt;li&gt;Finally, add created message to &lt;code&gt;SmsAdvancedTextualRequest&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;SendSmsMessage method from Infobip library will do the trick and send the message to our user:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;smsResponse&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sendSmsApi&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SendSmsMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;smsRequest&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Now that the basic functionality is up and running, adding it to your scheduler shouldn't be a problem. &lt;/p&gt;
&lt;h3&gt;
  
  
  ⏰ &lt;strong&gt;Second Step: Add scheduler&lt;/strong&gt; ✔️
&lt;/h3&gt;

&lt;p&gt;For this feature we will use Quartz.NET. &lt;br&gt;
One could describe Quartz.NET as a full-featured, open-source job-scheduling system.&lt;/p&gt;

&lt;p&gt;There are two important points you need to know; Job Scheduling and Job Execution.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Job Scheduling&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Jobs are scheduled to run when a given trigger occurs, triggers support wide variety of scheduling options.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;2. Job Execution&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Jobs can be any .NET class that implements the simple &lt;code&gt;IJob&lt;/code&gt; interface, leaving infinite possibilities for the work that jobs can perform.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Lets's add package to our project:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;dotnet add package Quartz.Extensions.Hosting
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Now, we have to configure and register our Quartz service. Use &lt;em&gt;Program.cs&lt;/em&gt; for that. You can follow documentation &lt;a href="https://www.quartz-scheduler.net/"&gt;https://www.quartz-scheduler.net/&lt;/a&gt; on how to configure and register in detail. &lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;p&gt;In this code example, we try to keep &lt;em&gt;Program.cs&lt;/em&gt; as short as possible, hence the extension method for our settings.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h3&gt;
  
  
  ⏲️ &lt;strong&gt;Third Step: Send SMS periodically&lt;/strong&gt; ✔️
&lt;/h3&gt;

&lt;p&gt;Scheduler is all set up and now you need to add jobs. In our report feature we decided to send SMS messages daily, weekly and monthly. &lt;/p&gt;

&lt;p&gt;Example &lt;a href="https://github.com/dlozina/url-shortener-service-v2"&gt;project&lt;/a&gt; has three jobs defined in project Jobs folder.&lt;/p&gt;

&lt;p&gt;Remember: &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Jobs can be any .NET class that implements the simple &lt;code&gt;IJob&lt;/code&gt; interface.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Example code below sends daily SMS report of how many URLs are shortened:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;You may ask yourself: Where is the scheduled time in this code? How can I change it?&lt;/p&gt;

&lt;p&gt;Well…that is the beauty of Quartz - it uses Cron expression which is easy to set up.&lt;br&gt;
For example, we have moved scheduler setup to our application settings, so there are separate settings for every job in our application.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;You can check out for various settings on &lt;a href="https://www.quartz-scheduler.net/documentation/quartz-3.x/tutorial/crontriggers.html"&gt;cron triggers&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In our example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Cron expression: "0 0 8 ? * MON-SUN" -&amp;gt; Daily - MON-SUN on 08:00 CET for the previous day&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Cron expression: "0 1 8 ? * MON" -&amp;gt; Weekly - MON on 08:01 CET for the past week&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Cron expression: "0 2 8 * * MON#1" -&amp;gt; Monthly - first MON on the month for the past month&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you go back to &lt;em&gt;Program.cs&lt;/em&gt; you will see how we grab and use this settings with our extension method.&lt;/p&gt;

&lt;p&gt;Now our web service is ready to send scheduled reports to users.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;&lt;em&gt;Conclusion 🎉 🍾&lt;/em&gt;&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;It comes as no surprise that scheduling jobs in applications can be a really daunting work. Quartz makes it so much easier. Bare in mind that we just scratched the surface with our settings. There is a lot more stuff under the hood but probably this is enough for most of use cases.&lt;/p&gt;

&lt;p&gt;The same thing can be said about our SMS notification feature. You don't need to write API request to Infobip platform. Just add library to your .NET project, set config, create your message objects and than send an SMS. It is also possible to expand this simple example and send reports with other&lt;br&gt;
information channels, such as Email and Whatsapp.&lt;br&gt;
Find other available options on &lt;a href="https://www.infobip.com/docs/api"&gt;Infobip Api&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Stay well,&lt;/p&gt;

&lt;p&gt;Dino&lt;/p&gt;

</description>
      <category>dotnet</category>
      <category>csharp</category>
      <category>tutorial</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Don't go OpenAPI first, go API first</title>
      <dc:creator>Ivan Letenko</dc:creator>
      <pubDate>Wed, 17 Nov 2021 10:16:49 +0000</pubDate>
      <link>https://forem.com/infobipdev/dont-go-openapi-first-go-api-first-bad</link>
      <guid>https://forem.com/infobipdev/dont-go-openapi-first-go-api-first-bad</guid>
      <description>&lt;p&gt;Despite the fact that API first approach has been around for many years, interest in it does not decrease and new articles are published.&lt;/p&gt;

&lt;p&gt;There's a lot of interest thanks to the popularity of microservices and distributed systems, as well as actively growing as-a-Service solutions and add-ons marketplaces where developers can build and publish their applications and APIs on top platform's APIs.&lt;/p&gt;

&lt;p&gt;Technical articles and presentations on API-first mainly focus on the technical implementation and use of certain tools, such as back-end code generation from &lt;a href="https://www.openapis.org"&gt;OpenAPI specification&lt;/a&gt;, as well as rising interest to &lt;a href="https://www.asyncapi.com"&gt;AsyncAPI specification&lt;/a&gt; that brings standard to event-driven architectures.&lt;/p&gt;

&lt;p&gt;However, I think it is important not to confuse goals and methods of achieving them; remember the basics of API first!&lt;/p&gt;

&lt;h2&gt;
  
  
  What is API first?
&lt;/h2&gt;

&lt;p&gt;First of all, it is a development process and strategy.&lt;/p&gt;

&lt;p&gt;Think about your API as a product for other developers even if it's an internal service. Apply agile development principles to the API design and definition. This allows us to establish a contract for how the API is supposed to behave. This contract is crucial because it improves the interaction of developers and allows you to get a system consisting of a reusable, and extensible building blocks, which brings a great value for business.&lt;/p&gt;

&lt;p&gt;An analogy is a test driven development (TDD), since it's also API first approach. Start with an interface, and the test will be the first consumer of your API.&lt;/p&gt;

&lt;p&gt;The API contract itself can be specified in various ways which depend on the specifics of project and context.&lt;br&gt;
It could be an OpenAPI specification, request/response JSONs, or interfaces.&lt;/p&gt;

&lt;p&gt;For example, at Infobip most of the services define their API through Java interfaces and data models, on the basis of which the OpenAPI specification is generated, if necessary.&lt;br&gt;
If you are designing an API for a web or mobile client of your service, design it as a product for external clients in order to avoid situations when you need to develop separate APIs for every new use cases.&lt;/p&gt;

&lt;p&gt;The benefits of an API first approach are similar to agile development processes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Fast feedback that allows you to make adjustments earlier while the cost of change is low;&lt;/li&gt;
&lt;li&gt;No constraints inherited from wrong abstractions &amp;amp; data models, you better understand customer needs by collaboratively discussing and adapting APIs&lt;/li&gt;
&lt;li&gt;Decoupling &amp;amp; parallelisation of work, teams can work independently having a common source of truth in the form of an API contract.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What is code first?
&lt;/h2&gt;

&lt;p&gt;With a more traditional code first approach, the main functionality of the application is first developed and then an API for consumers and contributors is inserted on top of it.&lt;/p&gt;

&lt;p&gt;This approach works well only for small APIs, mainly internal, when requirements are clear and stable.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tools &amp;amp; Workshops We Use For 1600 Applications
&lt;/h2&gt;

&lt;p&gt;Let's see briefly how we deal with internal &amp;amp; external APIs at Infobip. Infobip is a global communication platform that consists of over 1600 applications (service types) with hundreds of databases, data pipelines and support systems. More than 80 engineering teams work on. We have about 20 products that expose public APIs. At this scale it is vital for us to have reliable tools that synchronize and standardize service interactions while maintaining flexibility and speed of development.&lt;/p&gt;

&lt;p&gt;As I mentioned, most of our internal services are written in Java or Kotlin. They expose their APIs as Java interfaces (we call them "connectors") and register them in home crafted remoting system. This system transparently builds HTTP APIs for inter-service communication. For non-JVM services we use sidecar pattern.&lt;/p&gt;

&lt;p&gt;Dependent services can just import "connectors" and use them without worrying about implementation. In this way, the contract is defined and development is completely independent.&lt;/p&gt;

&lt;p&gt;For APIs that should be exposed publicly we use a solution based on &lt;a href="https://springdoc.org"&gt;springdoc-openapi&lt;/a&gt; that generates OpenAPI specification from Java/Kotlin classes. Non JVM services can expose OpenAPI specification by themselves on a dedicated endpoint. Thus, regardless of how the specification is created, it is a public contract.&lt;/p&gt;

&lt;p&gt;From that specification we generated &lt;a href="https://www.infobip.com/docs/api"&gt;public documentation&lt;/a&gt; and &lt;a href="https://www.infobip.com/docs/sdk"&gt;client libraries&lt;/a&gt; using &lt;a href="https://openapi-generator.tech"&gt;OpenAPI Generator&lt;/a&gt; based pipeline. Library generation also helps maintain the quality and stability of specifications.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--RA4KQ4ZR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/guv33em5dfiis21l5vh8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--RA4KQ4ZR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/guv33em5dfiis21l5vh8.png" width="880" height="353"&gt;&lt;/a&gt;&lt;br&gt;API docs &amp;amp; libs generation flow
  &lt;/p&gt;

&lt;h2&gt;
  
  
  What Works For Us At Infobip
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Focus on API design before development;&lt;/li&gt;
&lt;li&gt;Treat your API as a public product;&lt;/li&gt;
&lt;li&gt;Tools &amp;amp; workflows are secondary.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In most cases, there is no need to dive into the complexity of OpenAPI right away.&lt;/p&gt;

&lt;p&gt;OpenAPI has essentially become an industry standard and it is easy to use as a common language between components that guarantees interoperability and simplifies API management.&lt;/p&gt;

&lt;p&gt;If you want to know more on this topic give some likes &amp;amp; comments ;)&lt;/p&gt;

</description>
      <category>api</category>
      <category>openapi</category>
      <category>infobip</category>
    </item>
    <item>
      <title>How to write URL shortener in .NET5? We've made it seem easy #1</title>
      <dc:creator>Dino Lozina</dc:creator>
      <pubDate>Thu, 11 Nov 2021 09:10:04 +0000</pubDate>
      <link>https://forem.com/infobipdev/how-to-write-url-shortener-in-net5-weve-made-it-seem-easy-1-5c56</link>
      <guid>https://forem.com/infobipdev/how-to-write-url-shortener-in-net5-weve-made-it-seem-easy-1-5c56</guid>
      <description>&lt;p&gt;Welcome to our tutorial series, a place to be for those looking for a quick and efficient guide to writing URL shortener.&lt;br&gt;&lt;br&gt;
In this series we will try to show you how easy it is to write a service that shortens URLs with .NET5. On top of that, we will add an additional functionality - service will have to send an SMS when target URL is shortened and periodically send SMS reports.&lt;/p&gt;

&lt;p&gt;Stick with me until the end and you will learn how to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Create youtube like links for short URLs&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Use embedded NoSQL database&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Schedule web service, ex. send reports every day, week and/or month&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Send SMS from our service&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Just to give you heads up, this is by no means an extensive tutorial on how to build production grade shortening systems. For production grade systems we need to take into account scale and load. It would be nice to have some kind of analytics, but we have to start from somewhere, right?&lt;/p&gt;

&lt;p&gt;Software engineering nowadays can be compared to playing with LEGO bricks. All the nice bricks are out there, we need to implement them in a smart way. We don't want to reinvent the wheel every time we start programming, so we're going to use a couple of packages to make all this magic happen.&lt;/p&gt;

&lt;p&gt;First, we're going to need some SDK-s and tools:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;For IDE we can use (&lt;a href="https://code.visualstudio.com/"&gt;https://code.visualstudio.com/&lt;/a&gt;)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;We need .NET core SDK (&lt;a href="https://dotnet.microsoft.com/download"&gt;https://dotnet.microsoft.com/download&lt;/a&gt;)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Postman (&lt;a href="https://www.postman.com/downloads/"&gt;https://www.postman.com/downloads/&lt;/a&gt;)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;On my &lt;a href="https://github.com/dlozina/url-shortener-service-v2"&gt;github&lt;/a&gt; you will find the finished project so there's no need for you to write code yourself.&lt;/p&gt;

&lt;p&gt;Once we have .NET framework in place we will just check if everything is working for us with (type in terminal):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;dotnet --version
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;After the test we can create our template project:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;dotnet new webapi -n "Shortener.Service" -lang "C#" -au none
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;*&lt;em&gt;parameter -au none means there is no default authentication for our webapi&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;With this command we get template webapi project. Now that we have all things up and running let’s start with step by step guide.&lt;/p&gt;
&lt;h3&gt;
  
  
  🎮 &lt;strong&gt;First Step: Create controller methods ✔️&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Remove default web api controller and create your own. For this simple example we will have one GET and one POST method.&lt;/p&gt;

&lt;p&gt;Let’s dig into POST method. User will provide us with URL (simple UrlDataDto object) that needs to be shortened. We will store that URL we will store in LiteDB.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;p&gt;GET method needs a parameter shortUrl. If we have that shortUrl in our database, method will redirect us to “long” URL if request was made by browser. Request could also be made by “thin” client like Postman, so we will make sure that we return JSON with “long” URL. (In that case we don’t want to redirect) &lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h3&gt;
  
  
  💾 &lt;strong&gt;Second Step: Add database ✔️&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;As mentioned, we need DB to store our shortened URLs. For this small service we really don’t want to install DB or do something beforehand. Goal is just to “press play” and our app is ready to go.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;dotnet add package LiteDB
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;This will give us small NoSql database, perfect for our proof of concept.&lt;/p&gt;

&lt;p&gt;Now we need to link our application with DB:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;h3&gt;
  
  
  ⚙️ &lt;strong&gt;Third Step: Add services ✔️&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;As you can see, our controller is simple and whole business logic is in services. Let’s just check what we did in services.&lt;/p&gt;

&lt;p&gt;First of all, let's create service that will write data to our DB.&lt;/p&gt;

&lt;p&gt;Add to DB:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Get from DB:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;We need logic that will shorten our URL. For this we can use cool package Hashids.net and get youtube like short ids. We can chose length and "salt" for our links. Check out &lt;a href="https://github.com/ullmark/hashids.net"&gt;hashids.net&lt;/a&gt; for short instructions.&lt;/p&gt;

&lt;p&gt;For example, if we sent UrlDataDto:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "url": "https://www.infobip.com/docs/api"
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;We get in response nice youtube-like short links:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "url": "http://localhost:8000/V1oExr"
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Let's add this feature:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;dotnet add package Hashids.net
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Method in service for encode:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;p&gt;As you can see, we will encode DB id and generate our short URL from that data. (We will use this service in POST method)&lt;/p&gt;

&lt;p&gt;Method in service for decode:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Vice versa, on the other endpoint (our GET method) we will decode shortUrl to get id.&lt;/p&gt;

&lt;h3&gt;
  
  
  🧪 &lt;strong&gt;Fourth Step: Test with Postman ✔️&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;After &lt;code&gt;dotnet build&lt;/code&gt; and &lt;code&gt;dotnet run&lt;/code&gt; commands you are all set for manual test! Postman collections for you will find as part of the project, so that you can easily import.&lt;/p&gt;

&lt;p&gt;POST:&lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkak83l78wo1yy4l7aym9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkak83l78wo1yy4l7aym9.png" alt="Post method in Postman" width="753" height="349"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;GET:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2tm6zlxgyvtvixyr3tn7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2tm6zlxgyvtvixyr3tn7.png" alt="Get method in Postman" width="751" height="335"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;&lt;em&gt;That's all, folks! Or is it? 🎉 🍾&lt;/em&gt;&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;In part one of this series, we have created a simple URL shortener. We've showed you how to save data without installing database and generate short URLs with Hashids.net.&lt;/p&gt;

&lt;p&gt;Application passed our manual test with Postman, and we have set up stage to implement notifications in our web service.&lt;/p&gt;

&lt;p&gt;In part two of this series, we will learn how to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Schedule tasks in .NET applications&lt;/li&gt;
&lt;li&gt;Send SMS via Infobip platform&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>dotnet</category>
      <category>csharp</category>
      <category>tutorial</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Infobip WebRTC - A Quick Setup &amp; Test Guide</title>
      <dc:creator>Adnan Arnautović</dc:creator>
      <pubDate>Wed, 10 Nov 2021 08:07:52 +0000</pubDate>
      <link>https://forem.com/infobipdev/infobip-webrtc-a-quick-setup-test-guide-54e3</link>
      <guid>https://forem.com/infobipdev/infobip-webrtc-a-quick-setup-test-guide-54e3</guid>
      <description>&lt;p&gt;You know the usual developer drill - you sit down, ideas come and go, you filter the ones that work and write it all in a single go? Erm, not really!&lt;/p&gt;

&lt;p&gt;When we start writing new software, there is always the stage of planning and deliberating about which technologies to use and which dependencies can help us make the best software for our use-cases and potential clients. This is where having the right tool is crucial for making the best decisions. If you are looking to integrate real-time communications into your application, we already have one of those tools in mind for you.&lt;/p&gt;

&lt;h1&gt;
  
  
  Why integrate RTC into your application in the first place?
&lt;/h1&gt;

&lt;p&gt;You might ask yourself "Why would I use WebRTC anyway? Can't I just call someone over the phone?". Sure you can, but think about the different scenarios that could happen and the platform that could address them all. For instance, if you want to show someone a certain product or let them check something from a distance, you can use video calls over WebRTC to provide this service. Or let's say you're out on the road and you've just had an accident which you need to report to your supervisor. With WebRTC this could be as easy as having a two-minute video call.&lt;/p&gt;

&lt;h2&gt;
  
  
  Communicate across devices with multiple participants
&lt;/h2&gt;

&lt;p&gt;By using WebRTC you can also employ many other devices, not just mobile phones, for your communication needs. If there is an office employee contacting multiple colleagues that work on the terrain, he or she can sit at their computer and still talk to the colleagues using their phones. If there's a need to talk to multiple people at once, WebRTC will make it happen quick and easy via the conferencing feature.&lt;/p&gt;

&lt;h2&gt;
  
  
  Record calls and keep track of communications
&lt;/h2&gt;

&lt;p&gt;Recording calls, be it 1-on-1 or conference, is something not only useful, but also sometimes required by regulatory measures. With WebRTC you can choose to record your calls whenever you want and keep track of your communications when needed.&lt;/p&gt;

&lt;p&gt;All of the above shows that with WebRTC you can harness the true power of your communications, implement more communication channels, and make the life of your clients and employees easier. If you want to test it out yourself, we've prepared a detailed setup guide. To be able to follow this showcase setup, please login to &lt;a href="https://portal.infobip.com/" rel="noopener noreferrer"&gt;Infobip Portal&lt;/a&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  What is Infobip RTC Showcase?
&lt;/h1&gt;

&lt;p&gt;The Infobip RTC Showcase is a collection of simple apps implementing our Web and In-app Calls communication channel using WebRTC. These apps enable you to setup a simple WebRTC app and test its features out on your own, even change the code and experiment.&lt;/p&gt;

&lt;p&gt;The following app examples are present in our showcase:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Kotlin&lt;/li&gt;
&lt;li&gt;Swift&lt;/li&gt;
&lt;li&gt;React Native&lt;/li&gt;
&lt;li&gt;Angular&lt;/li&gt;
&lt;li&gt;jQuery&lt;/li&gt;
&lt;li&gt;React&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Considering the main purpose of this app, you will also notice that the user interface is basic. This enables everyone to easily change the code in a matter of minutes and test out new things if they are interested.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Feo1ra5i89lm052jnsnvc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Feo1ra5i89lm052jnsnvc.png" alt="Infobip RTC simple user interface"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Of course, if you are going to use the RTC Showcase and integrate WebRTC into your own app in the future, you will need to fulfil some prerequisites.&lt;/p&gt;

&lt;h1&gt;
  
  
  What to Know Before You Start?
&lt;/h1&gt;

&lt;p&gt;To be able to use Infobip RTC Showcase, you first need to have certain things installed:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Node.js&lt;/li&gt;
&lt;li&gt;Java, version 12&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Next, you will have to set up the token application for the showcase applications. The token application is used to fetch the Infobip token you need for authenticating your identity when accessing Infobip's backend. Here you have two options, depending on the technology you want to test out with the showcase.&lt;/p&gt;

&lt;h2&gt;
  
  
  JavaScript Token Application
&lt;/h2&gt;

&lt;p&gt;To be able to run the JavaScript-based token application, you will need to add a &lt;strong&gt;config.json&lt;/strong&gt; file to the &lt;strong&gt;token/node&lt;/strong&gt; folder with the following structure:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;The &lt;strong&gt;HTTP_PORT&lt;/strong&gt;, &lt;strong&gt;INFOBIP_API_HOST&lt;/strong&gt;, and &lt;strong&gt;INFOBIP_RTC_TOKEN_PATH&lt;/strong&gt; parameters are used to set the port on which your token app will run, and the host and path from which your token will be fetched. These values will be the same for everyone using our RTC showcase, although you can freely change the &lt;strong&gt;HTTP_PORT&lt;/strong&gt; if the predefined port is taken. To be able to use the new port for the token application, do not forget to change the port in every respective application to the new one.&lt;/p&gt;

&lt;p&gt;The more important parts of this config file are &lt;strong&gt;INFOBIP_API_KEY&lt;/strong&gt; and &lt;strong&gt;INFOBIP_APP_ID&lt;/strong&gt;. You can get both values from the &lt;a href="https://portal.infobip.com/" rel="noopener noreferrer"&gt;Infobip Portal&lt;/a&gt; after you have logged in into your account.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;To get &lt;strong&gt;INFOBIP_API_KEY&lt;/strong&gt; you will need to access the "Manage API keys" site from the Portal dashboard (&lt;a href="https://portal.infobip.com/settings/accounts/api-keys" rel="noopener noreferrer"&gt;Manage API keys&lt;/a&gt;) and copy your chosen API key into the config.json file&lt;/li&gt;
&lt;li&gt;To get &lt;strong&gt;INFOBIP_APP_ID&lt;/strong&gt; you will need to access the "Apps &amp;gt; Web and In-App Calls &amp;gt; Applications" site (&lt;a href="https://portal.infobip.com/apps/webrtc/" rel="noopener noreferrer"&gt;My Applications&lt;/a&gt;) and copy your chosen APP ID into the config.json file&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When you have filled out the required information in the config.json file, you will need to do two more steps with the token application before you are ready to go onto the showcase applications. First go to the &lt;strong&gt;token/node&lt;/strong&gt; folder through your terminal/command prompt and then:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Run &lt;strong&gt;npm install&lt;/strong&gt;, which will install the packages needed for the token application&lt;/li&gt;
&lt;li&gt;Run &lt;strong&gt;npm start&lt;/strong&gt;, which will start the application on &lt;a href="http://localhost:8080" rel="noopener noreferrer"&gt;http://localhost:8080&lt;/a&gt; (If you have not changed the port in the config.json file)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now you can start running and experimenting with the showcase applications that can be found in the &lt;strong&gt;js/&lt;/strong&gt; folder, but if you want to be sure that the token application is running, you can run&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;If your token application is running, this will return a JSON object like the following&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h2&gt;
  
  
  Java Token Application
&lt;/h2&gt;

&lt;p&gt;To be able to run the Java-based token application, you will need to add two environment variables with the values for &lt;strong&gt;INFOBIP_API_KEY&lt;/strong&gt; and &lt;strong&gt;INFOBIP_APP_ID&lt;/strong&gt;. You can add the environment variables in several ways depending on the operating system you are using, and which approach you prefer. To set the environment variables through the terminal/command prompt:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;For Unix-like operating systems (Mac OS and GNU+Linux)
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;For Windows operating systems
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If we look at &lt;strong&gt;token/java/src/main/resources/application.yml&lt;/strong&gt;, where you will find the following code&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;We will see that we can also easily change the &lt;strong&gt;HTTP_PORT&lt;/strong&gt; value if needed. We just need to set the &lt;strong&gt;HTTP_PORT&lt;/strong&gt; environment variable on our system, and our token application will prioritize that value.&lt;/p&gt;

&lt;p&gt;After setting up the environment variables, we just need to run the following command from inside the &lt;strong&gt;token/java&lt;/strong&gt; folder:&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;This will start the token application which is built with the Java Spring Boot framework. We can check if our token application is up and running by using the same command as the last time&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;If your token application is running, this will also return a JSON object like the last time&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;Keep in mind:&lt;/strong&gt; If you want to run both token applications at the same time, you will need to change the &lt;strong&gt;HTTP_PORT&lt;/strong&gt; value for at least one of them.&lt;/p&gt;

&lt;h1&gt;
  
  
  Showcase Applications
&lt;/h1&gt;

&lt;p&gt;Showcase applications will use the token application to authenticate users on Infobip platform, so be sure to set up the token applications correctly before continuing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Change Needed Configurations
&lt;/h2&gt;

&lt;p&gt;If you have changed the &lt;strong&gt;HTTP_PORT&lt;/strong&gt; inside the token application's configuration, you will first need to change the port for the token application inside showcase applications from 8080 to your preferred port.&lt;/p&gt;

&lt;p&gt;Also, if you want to change the ports that the JavaScript-based showcase applications are using, you can do that by:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;jQuery&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Changing the &lt;strong&gt;HTTP_PORT&lt;/strong&gt; value in &lt;strong&gt;js/jquery/app.js&lt;/strong&gt; from 8010 to your preferred port&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;React&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Changing the &lt;strong&gt;PORT&lt;/strong&gt; value in &lt;strong&gt;js/react/package.json&lt;/strong&gt; from 8020 to your preferred port&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Angular&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Changing the &lt;strong&gt;port&lt;/strong&gt; option in the ng serve command in &lt;strong&gt;js/angular/package.json&lt;/strong&gt; from 8030 to your preferred port&lt;/p&gt;

&lt;h2&gt;
  
  
  Add Google Services to Android Showcase Applications
&lt;/h2&gt;

&lt;p&gt;To be able to receive notifications on incoming calls from Infobip showcase applications, you will need to add a Firebase configuration file to the app (step 3 &lt;a href="https://firebase.google.com/docs/android/setup" rel="noopener noreferrer"&gt;here&lt;/a&gt;) named &lt;strong&gt;google-services.json&lt;/strong&gt; to the app.&lt;/p&gt;

&lt;p&gt;Depending on the project, you will need to add the &lt;strong&gt;google-services.json&lt;/strong&gt; file in a different place:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Android Kotlin&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Add the &lt;strong&gt;google-services.json&lt;/strong&gt; file to &lt;strong&gt;android/kotlin/infobip-rtc-showcase-android&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;React Native&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Add the &lt;strong&gt;google-services.json&lt;/strong&gt; file to &lt;strong&gt;react_native/android/app&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Here you can also make sure that you add the correct path to the Android SDK (Software Development Kit) on your computer on the React Native showcase application. You can set this in &lt;strong&gt;react_native/android/local.properties&lt;/strong&gt; on the &lt;strong&gt;sdk.dir&lt;/strong&gt; property.&lt;/p&gt;

&lt;h2&gt;
  
  
  Running JavaScript-based Showcase Applications
&lt;/h2&gt;

&lt;p&gt;If you have gotten to this step and the token application inside &lt;strong&gt;token/node&lt;/strong&gt; or &lt;strong&gt;token/java&lt;/strong&gt; is running, then the following is straight forward. You just need to navigate to the folder for the chosen technology (be it jQuery, React, or Angular) and run the following&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;This will install and then run the application on the preferred port, which you can then access through your browser. To simply test out the application, you can start up two browser tabs and call the other user from one tab.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Keep in mind:&lt;/strong&gt; If you are running the React or Angular applications, the page will reload automatically if you make any edits. You will also be able to see any lint errors in the console.&lt;/p&gt;

&lt;h2&gt;
  
  
  Running Mobile Showcase Applications
&lt;/h2&gt;

&lt;p&gt;You can run the Android Kotlin and iOS Swift showcase applications as any other application through their respective IDEs (Android Studio and XCode) in the emulator. There is a known issue with receiving push notifications for incoming calls on subsequent runs on the emulator on all three mobile showcase applications (React Native, Kotlin, and Swift). This can be solved by wiping data from the emulator before running it again.&lt;/p&gt;

&lt;p&gt;You can also run the app on a real device, although you will need access to the token application from the device itself. You can enable this by using the &lt;strong&gt;ngrok&lt;/strong&gt; command, which allows you to expose your local port on the whole network. The following command will enable this:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Here you can also choose the preferred port to expose the token application.&lt;/p&gt;

&lt;p&gt;Unlike the Kotlin and Swift showcase applications, the React Native application will require you to do one more step. Run the following inside the &lt;strong&gt;react_native&lt;/strong&gt; directory:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;or you can also use yarn:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;The commands do the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Install needed dependencies&lt;/li&gt;
&lt;li&gt;Start the application&lt;/li&gt;
&lt;li&gt;Run the application on an Android emulator or your connected phone&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Keep in mind:&lt;/strong&gt; You can use either npm or yarn to run this application, but it is advised not to mix package managers to avoid resolution inconsistencies.&lt;/p&gt;

&lt;h1&gt;
  
  
  That's it. You're ready to go!
&lt;/h1&gt;

&lt;p&gt;For now, through the RTC Showcase applications you can look at:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;1-on-1 audio and video calls through WebRTC&lt;/li&gt;
&lt;li&gt;Sharing your screen during the call&lt;/li&gt;
&lt;li&gt;Calling a phone number using WebRTC&lt;/li&gt;
&lt;li&gt;Joining conferences with audio and video&lt;/li&gt;
&lt;li&gt;Sharing your screen during conferences&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you want to learn more about Web and In-Application Calls, you can visit &lt;a href="https://www.infobip.com/docs/voice-and-video/webrtc" rel="noopener noreferrer"&gt;Infobip's Voice and Video documentation for WebRTC&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Check if you already have access to our WebRTC Demo applications and try out the newest features over there:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://webrtc-demo.infobip.com/" rel="noopener noreferrer"&gt;Browser application&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://play.google.com/store/apps/details?id=com.infobip.webrtc.demo.android" rel="noopener noreferrer"&gt;Android application&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://apps.apple.com/us/app/infobip-webrtc/id1469234824" rel="noopener noreferrer"&gt;iOS application&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To enable Web and In-App Calls, contact your dedicated Account Manager or our &lt;a href="https://www.infobip.com/contact" rel="noopener noreferrer"&gt;Sales&lt;/a&gt; team.&lt;/p&gt;

&lt;p&gt;When you are ready to start integrating our SDKs into your own application, you are more than welcome to look at the reference documentation for various SDKs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/infobip/infobip-rtc-js/wiki" rel="noopener noreferrer"&gt;JavaScript SDK&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/infobip/infobip-rtc-android/wiki" rel="noopener noreferrer"&gt;Android SDK&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/infobip/infobip-rtc-ios/wiki" rel="noopener noreferrer"&gt;iOS SDK&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/infobip/infobip-rtc-react-native/wiki" rel="noopener noreferrer"&gt;React Native SDK&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you have any questions, we'd be happy to hear from You &lt;a href="https://www.infobip.com/contact" rel="noopener noreferrer"&gt;&lt;strong&gt;here&lt;/strong&gt;&lt;/a&gt;!&lt;/p&gt;

</description>
      <category>webrtc</category>
      <category>tutorial</category>
      <category>testing</category>
    </item>
    <item>
      <title>Email collections under GDPR - The right way</title>
      <dc:creator>Ivan Burazin</dc:creator>
      <pubDate>Mon, 01 Nov 2021 12:10:48 +0000</pubDate>
      <link>https://forem.com/infobipdev/email-collections-under-gdpr-the-right-way-2e2b</link>
      <guid>https://forem.com/infobipdev/email-collections-under-gdpr-the-right-way-2e2b</guid>
      <description>&lt;p&gt;You're a certain someone who works on development of a client-oriented technical solution(s)? You probably want to have the best ways to communicate to those who are consuming your services in a robust way and scale it easily? If that's all you then keep reading.&lt;/p&gt;

&lt;p&gt;This article has plenty of non-developer essential angles of email marketing covered, yet it emphasizes the need of conveying your messages properly. If you're not that interested in high-level why's and how's, but still are looking for the best solution (platform, APIs, SDK, portal, etc.) then I'd suggest you jump straight to the solution we linked for you below and start playing with it.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is email marketing and why should you care?
&lt;/h2&gt;

&lt;p&gt;In earlier years it was possible to collect and use consumer data with little restrictions (if any). Lately, however, with all the data privacy topics being in the focus it is now a service provider who must be careful on how is he approaching service consumers.&lt;/p&gt;

&lt;p&gt;With email marketing, you can create long-lasting connections with your consumers. It's the process of sending commercial emails to those on your list who have given permission for us to contact them through email by subscribing - and people love getting &lt;strong&gt;great&lt;/strong&gt; offers!&lt;/p&gt;

&lt;p&gt;An example campaign would include an automated message sent at 9 AM every morning reminding customers about some exciting deals happening now only available via this link which will take 10 minutes off their purchase time - what are they waiting for!?&lt;/p&gt;

&lt;p&gt;When it comes to small companies, it is one of the most cost-effective options. It's critical to realize that a large part of your success is entirely dependent on the email marketing software you select since they are ultimately responsible for ensuring that your emails get sent. If you're not cautious, you'll find yourself paying much more for fewer marketing options and poor email deliverability rates.&lt;/p&gt;

&lt;p&gt;If you are looking for a reliable email solution, look no further than &lt;a href="https://www.infobip.com/"&gt;Infobip&lt;/a&gt;. Infobip platform handles plenty of communication channels, and email is just one of them. Check how simple it is to incorporate our solution into your product and choose for yourself if it meets all of your requirements. Our &lt;a href="https://medium.com/r/?url=https%3A%2F%2Fwww.infobip.com%2Fdocs%2Fessentials%2Ffree-trial"&gt;free trial&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;will assist you in familiarizing yourself with our solution, understanding integration, and recognizing the best possibilities with our solution.&lt;/p&gt;

&lt;h2&gt;
  
  
  How much do you need to worry about GDPR?
&lt;/h2&gt;

&lt;p&gt;General Data Protection Regulation (GDPR) is a new set of European Union regulations governing the handling of personal data. Due to the constant development of the digital world, the GDPR is intended to bring prior data protection regulations up to date. It is designed to improve data protection inside the EU by implementing rules (and fines!) regarding personal data processing, acquisition, and storage.&lt;/p&gt;

&lt;p&gt;The GDPR applies to your business if it processes, saves, or utilizes the personal data of EU people. Personal data includes email addresses, names, phone numbers, and behavioral data about your consumers. It is critical to remember that the rules apply to personal data transferred beyond the EU (to the US, for example).&lt;/p&gt;

&lt;p&gt;Businesses may send email marketing to people only if the following conditions are met:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The person has expressly agreed.&lt;/li&gt;
&lt;li&gt;They are a current client who purchased a comparable service or product and was provided with an easy method to opt-out.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The rise of social media has changed the way we interact with brands. In many cases, companies will send customers emails without their permission because they haven't unsubscribed from marketing lists or opted out - even if you don't want the communication! The best thing a person can do is check your inbox for any unsolicited messages and make sure that nobody else could have access to it either - only signing up using one email address should be enough protection against bad actors trying too hard to sell everything all at once… but let's face it: Most people just end up clicking "yes" anyways; whether on purpose or not doesn't really matter as long as there isn't an Automated Response waiting.&lt;/p&gt;

&lt;p&gt;To be acceptable, however, they must have been provided a clear and simple option to opt out. This should be made available when their first data is taken and should be included in any future messages delivered.&lt;br&gt;
This regulation implies that, although information may be given to current customers by email or text, it does not apply to new contacts or prospective consumers. Additionally, it does not apply to any promotional activity that is not commercial, such as political campaigning or charity fundraising.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why is the Subscriber's consent important?
&lt;/h2&gt;

&lt;p&gt;The GDPR imposes strict requirements on how you get, record, and maintain permission for marketing communications. In reality, this implies that people providing you with their email address must express permission actively and openly before you may send them emails.&lt;/p&gt;

&lt;p&gt;Consent must be provided voluntarily. This implies that it cannot be accomplished via the use of a pre-ticked box. Apart from that, explicit permission is essential. This means that the client must understand what they are signing up for.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--8_6c21ay--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/y0vleknwxswyfgprv7fu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8_6c21ay--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/y0vleknwxswyfgprv7fu.png" alt="Image description" width="800" height="525"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Take note that if you are contacted, you must provide evidence of the permission provided. It is critical, then, that you maintain a record of all consents granted by your subscribers.&lt;br&gt;
You may send emails without obtaining permission. Rather than relying on consent, you may claim that you distribute newsletters to further your company's legitimate interests. However, and this is critical, the individual you are sending emails to should have some connection with you, such as having purchased one of your goods. It is up to each business to choose which approach is most appropriate for them - whether via consent or legitimate interests - and ensure compliance with the GDPR.&lt;/p&gt;

&lt;h2&gt;
  
  
  Email Marketing After GDPR implementation
&lt;/h2&gt;

&lt;p&gt;Email marketing is a popular kind of advertising that was formerly very simple to deploy. However, with the implementation of GDPR, there is another area that needs careful attention.&lt;/p&gt;

&lt;p&gt;For example, businesses must get express permission from their contacts before continuing to send them emails. This necessitates a more rigorous membership procedure that includes a double opt-in and an easy opt-out option and prohibits forced or compelled opt-ins.&lt;/p&gt;

&lt;p&gt;A double opt-in verifies that users want to receive emails, filtering out fraudulent or negligent requests (for example, a user's failure to uncheck an automatically selected subscription box). If a customer gives their email address for a subscription, they will be required to consent to it a second time in their email.&lt;/p&gt;

&lt;p&gt;The need for double opt-in serves as a safeguard for businesses that send promotional emails. Anybody subscribing to your emails should do so freely and without feeling compelled to do so in exchange for a specific product or service. Additionally, they should be able to unsubscribe from your email list at any moment without suffering any consequences.&lt;/p&gt;

&lt;h2&gt;
  
  
  To conclude
&lt;/h2&gt;

&lt;p&gt;Well, we discussed that GDPR refocused marketers on established email best practices, further strengthening marketing campaigns for those already committed to providing superior customer experiences.&lt;/p&gt;

&lt;p&gt;Now, these similar standards and guidelines advise subscribers how they will hear from you and how they want to communicate with you. As we've seen, this puts your marketing efforts in an ideal position to connect with a genuinely engaged audience, enabling you to deliver high-performing messages that impact your revenue. As marketers, we can now target and plan with more zeal, laser-focused on the information we have about our consumers. Now, their expectations have the potential to impact our companies significantly.&lt;br&gt;
Moreover, using the right platforms can help create robust email solutions for their services, which helps in creating highly interactive email newsletters quickly and easily with robust solutions.&lt;/p&gt;

&lt;p&gt;Feel free to sign up for our &lt;a href="https://medium.com/r/?url=https%3A%2F%2Fwww.infobip.com%2Fdocs%2Fessentials%2Ffree-trial"&gt;trial&lt;/a&gt; account to test out how we solve communication challenges! There you can experience how to integrate &lt;a href="https://www.infobip.com/docs/essentials/free-trial"&gt;Infobip&lt;/a&gt;communication platform into your technical solution(s) and how it might help you expand the business.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Let’s Talk About Executing and Caching Queries with React Apollo</title>
      <dc:creator>Danko Šimunović</dc:creator>
      <pubDate>Wed, 27 Oct 2021 16:45:31 +0000</pubDate>
      <link>https://forem.com/infobipdev/lets-talk-about-executing-and-caching-queries-with-react-apollo-15f1</link>
      <guid>https://forem.com/infobipdev/lets-talk-about-executing-and-caching-queries-with-react-apollo-15f1</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--HpTjgPLb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/13ynlmycoph96dp9tem4.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--HpTjgPLb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/13ynlmycoph96dp9tem4.jpg" alt="Cover photo" width="880" height="497"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Yep, you’ve guessed it. We’re going to talk about queries. &lt;/p&gt;

&lt;p&gt;Let’s start with basics. The &lt;code&gt;useQuery&lt;/code&gt; React hook is the primary API for executing queries when using Apollo Client in React. To run a query within a React component, we call the &lt;code&gt;useQuery&lt;/code&gt;  and pass it a GraphQL query string. When the component renders, &lt;code&gt;useQuery&lt;/code&gt;  returns an object from Apollo Client that contains &lt;code&gt;loading&lt;/code&gt;, &lt;code&gt;error&lt;/code&gt;, and &lt;code&gt;data&lt;/code&gt; properties. &lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Apollo Query component is a deprecated way of executing queries. It’s a part of &lt;code&gt;@apollo/react-components&lt;/code&gt; package and it is implementing Render props pattern. Render props are used for sharing code between React components using a prop whose value is a function. A component with a render prop takes a function that returns a React element. The component then calls this function instead of implementing its own render logic. In the case of Query component, we are using the &lt;strong&gt;children&lt;/strong&gt; prop as a render prop. But because the children prop doesn’t need to be named in the list of “attributes”,  you can put it directly inside the element. In the following example, we are passing a query prop, which is required. &lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Internally, Query component actually uses the &lt;code&gt;useQuery&lt;/code&gt; hook and then calls the render props function with results returned from the hook. This means that we’re using the same options and are getting the same result object as when using the &lt;code&gt;useQuery&lt;/code&gt; hook. &lt;/p&gt;

&lt;h3&gt;
  
  
  Cache-first, Ask Questions Later
&lt;/h3&gt;

&lt;p&gt;Apollo is locally caching results for the queries by default. This makes subsequent executions of the same query extremely fast. This is called &lt;strong&gt;cache-first&lt;/strong&gt; policy. We can define fetch policy on query level.  &lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;These are 6 supported fetch policies: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;cache-first&lt;/strong&gt;: This is the default fetch policy. If data is present in the cache, that data is returned. Otherwise, a query is executed against the GraphQL server and the data is returned after it is cached. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;cache-only&lt;/strong&gt;: Query is only executed against the cache. GraphQL server is never called. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;cache-and-network&lt;/strong&gt;: If data is present in the cache, that data is returned. But even then, a query is executed against the GraphQL server. If the response differs from what is stored in the cache, it will update the cache. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;network-only&lt;/strong&gt;:  Query is executed against the GraphQL server, without first checking the cache. The query's result is stored in the cache in case the same query with a different fetch policy is being made elsewhere in the application. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;no-cache&lt;/strong&gt;: Behaves like network-only, except the query's result is not stored in the cache. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;standby&lt;/strong&gt;: Behaves like cache-first, except this query does not automatically update when underlying field values change. You have to update it manually. &lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There is also a possibility to define &lt;strong&gt;nextFetchPolicy&lt;/strong&gt; option. This way, you can define fetch policy for the first query execution using &lt;strong&gt;fetchPolicy&lt;/strong&gt; and then you can define fetch policy for the subsequent executions with &lt;strong&gt;nextFetchPolicy&lt;/strong&gt;. &lt;/p&gt;

&lt;h3&gt;
  
  
  Apollo Client Behind the Scenes
&lt;/h3&gt;

&lt;p&gt;Apollo Client acts as a facade to the underlying cached data. Behind the scenes, Apollo normalizes the data by splitting the results into individual objects and assigns a unique identifier to each object. These objects are stored in a flattened structure. Apollo then exposes an API to interact with the cached data. By minimizing direct access to the actual data using the facade/API, Apollo can normalize data under the hood. &lt;/p&gt;

&lt;p&gt;Apollo can &lt;strong&gt;automatically update cache&lt;/strong&gt; for: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Queries &lt;/li&gt;
&lt;li&gt;Mutations that update a single existing entity &lt;/li&gt;
&lt;li&gt;Bulk update mutations that return the entire set of changed items &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Of course, there are use cases in which we have to &lt;strong&gt;manually update the cache&lt;/strong&gt;: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Application-specific side-effects (something that happens after the mutation, but does not use data returned from the mutation) &lt;/li&gt;
&lt;li&gt;Update operations that add, remove, or reorder items in a cached collection &lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Manually Updating Cached Data
&lt;/h3&gt;

&lt;p&gt;Apollo supports multiple ways of reading and writing cached data:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;readQuery / writeQuery&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;readFragment / writeFragment&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;cache.modify&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With &lt;code&gt;readQuery&lt;/code&gt; method, it is possible to run GraphQL queries directly on the local cache. If the cache contains all of the data necessary to execute a specified query, &lt;code&gt;readQuery&lt;/code&gt; returns a data object in the shape of the query, just like a GraphQL server does.  If some fields are missing from the cache, &lt;code&gt;null&lt;/code&gt; is returned. Using &lt;code&gt;writeQuery&lt;/code&gt; we can write arbitrary data to the cache for the specific query. It looks similar to &lt;code&gt;readQuery&lt;/code&gt;, but it accepts &lt;code&gt;data&lt;/code&gt; option. &lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Using fragments it is possible to read or update only parts of the cached data, unlike &lt;code&gt;readQuery / writeQuery&lt;/code&gt; methods, which require a complete query. When using fragments to interact with cache, we can use &lt;code&gt;readFragment / writeFragment&lt;/code&gt; methods. They require &lt;code&gt;id&lt;/code&gt; option, which represents the unique identifier that was assigned to the object in the cache.  By default, this identifier has the format &lt;code&gt;&amp;lt;_typename&amp;gt;:&amp;lt;id&amp;gt;&lt;/code&gt;, but this can be customized. If there is no object with the specified ID, &lt;code&gt;readFragment&lt;/code&gt; returns &lt;code&gt;null&lt;/code&gt;.  &lt;code&gt;writeFramgent&lt;/code&gt; accepts &lt;code&gt;data&lt;/code&gt; option, which represents data that will be written for the specified object and that conforms to the specified fragment. &lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;With &lt;code&gt;cache.modify&lt;/code&gt; it is possible to directly modify cached fields. This method requires the ID of the cached object to modify and a modifier function for each field to modify. &lt;/p&gt;

&lt;p&gt;It is important to emphasize that any changes made with these methods are not pushed to the GraphQL server. If the current page is refreshed, these changes will disappear. Also, all methods trigger a refresh of all active queries that depend on modified fields. &lt;/p&gt;

&lt;h3&gt;
  
  
  Two Strategies for Updating the Cached Results
&lt;/h3&gt;

&lt;p&gt;Besides manually rewriting cached data, there are two strategies for updating the cached results: &lt;strong&gt;polling&lt;/strong&gt; and &lt;strong&gt;refetching&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;With polling, we execute the query periodically at a specified interval. &lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Refetching is done by using &lt;code&gt;refetch&lt;/code&gt; function that enables us to re-execute the query.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h3&gt;
  
  
  Apollo Client is a Powerful Caching Machine
&lt;/h3&gt;

&lt;p&gt;In conclusion, one would have to agree that Apollo Client is a mighty caching machine. It’s equipped with a powerful caching mechanism that makes it  easy to execute data queries quickly and efficiently. However, to make better use of its caching possibilities, one should get familiar with various methods of interacting with cache, cache setup and configuration. &lt;/p&gt;

</description>
      <category>graphql</category>
      <category>react</category>
      <category>javascript</category>
    </item>
    <item>
      <title>I am a code-monkey and so are you</title>
      <dc:creator>ZokiR</dc:creator>
      <pubDate>Wed, 29 Sep 2021 09:36:40 +0000</pubDate>
      <link>https://forem.com/infobipdev/i-am-a-code-monkey-and-so-are-you-56l4</link>
      <guid>https://forem.com/infobipdev/i-am-a-code-monkey-and-so-are-you-56l4</guid>
      <description>&lt;p&gt;We have all been code monkeys. And yes, I admit - I was the monkey too. And now I am the monkey sometimes, code-monkey that is. &lt;br&gt;
But what is a code-monkey? Is it a person, a role, or a strategy? &lt;br&gt;
It is a programmer with a simple and basic skill set, according to &lt;a href="https://www.techopedia.com/definition/31469/code-monkey"&gt;Techopedia&lt;/a&gt;. It's the first step after you finish your education in IT and you get your first job as a software developer.&lt;br&gt;
Now, I am a software engineer with 14+ experience in the industry and I look back to that time of the beginning when everything was simple. &lt;/p&gt;

&lt;p&gt;I didn't have to think about the whole mechanism and how it will work, just one simple gear at a time. It was a time when I have entered the world of professional software development with very little knowledge of anything but the programming language I worked with (C# Love), an entry-level code-monkey some would say. I could focus on my for... loops, my class naming, etc. &lt;/p&gt;

&lt;p&gt;If I had any questions, the "Engineers" had all the answers and the Senior Engineers were like Masters of their craft. When they lift a finger the solution appeared in front of you. And I was like 'I wanna be you...' and it happened, after many many highs and lows and years.&lt;/p&gt;

&lt;p&gt;Today I think about mechanisms, systems, concepts, patterns, designs, and coding is the last thing on to-do list for any solution. I love that. I love being an engineer but it is far more than lifting a finger. I have to bleed and also do the monkey code dance.&lt;/p&gt;

&lt;p&gt;Everybody in the development community has heard about the concept "Release early, release often". &lt;/p&gt;

&lt;p&gt;In one of my previous jobs, the humans responsible for company vision had a "new" vision, a new application that could sky rock us high in earnings but we had to be quick, we had to prove that idea is good. The plan was to make a few basic killer features the app has to offer, release it and get some paying customers. A typical startup story. We (the team) were excited and started working on the app's architectural design. Then it happened. The architect weighted in: We needed to think about security, data storage, hosting, scaling, UX, etc. &lt;/p&gt;

&lt;p&gt;Short story: we didn't release the app early. In fact, we didn't release it at all. We overengineered the damn thing. Sure, the junior developer who said to hardcode all we could and forget the concepts was WRONG, what a monkey!&lt;/p&gt;

&lt;p&gt;We need both code-monkeys and engineers in development teams.&lt;br&gt;
The natural path of learning and evolving as a software developer would be code-monkey (or junior) becoming an engineer. But how do we become engineers if we do only simple tasks with a basic skillset? We don't, we expand our skillset all the time. Learning new technologies, new design patterns, new solutions to our problems. So if we are doing that from the beginning aren't we also engineers? I think we are. &lt;/p&gt;

&lt;p&gt;We are both; code-monkeys and engineers all the time because after we think about big peace, big scope, big ideas, solutions we come down to little parts where we use our simple skillset to make them work. &lt;/p&gt;

&lt;p&gt;When we are pressed by our managers to fix a bug, it's always in a hurry, always some kind of fire we need to put out. Fix it now.. We'll rewrite it like we should… later! Come on, when do we honestly rewrite something if it works? Even in situations when everything is burning around us, we have to try to predict what could happen and how it will work down in the chain. &lt;br&gt;
Only then we can call ourselves "Engineers". However, correcting that crucial buggy for...loop that started all the mess could be the time when you use the code-monkey.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Code-monkey&lt;/strong&gt; is not a role, it is a strategy, a tool that you use in a day to do focused coding tasks. &lt;/p&gt;

&lt;p&gt;This strategy is used after everything else is completed, the assessment, the diagrams, the planning, the engineering work, and the only thing is left is to code it, make it happen. &lt;br&gt;
An experienced software engineers would say "that's the easy part", even a monkey could do it - but we do it. All of us, juniors, seniors, architects - no monkeys.&lt;/p&gt;

&lt;p&gt;When I don't want to do a task break down, don't want to talk to people, don't want to think about the whole system, and just want to work on good explained task and write code. It's is my time for a Code-Monkey!&lt;/p&gt;

&lt;p&gt;My question to you is: Are you a &lt;em&gt;code-monkey&lt;/em&gt;?&lt;/p&gt;

</description>
      <category>codemonkey</category>
    </item>
    <item>
      <title>Developers, Our Toolbelts Form Us!</title>
      <dc:creator>Alexey Maltsev</dc:creator>
      <pubDate>Mon, 27 Sep 2021 10:56:38 +0000</pubDate>
      <link>https://forem.com/infobipdev/developers-our-toolbelts-form-us-4dkn</link>
      <guid>https://forem.com/infobipdev/developers-our-toolbelts-form-us-4dkn</guid>
      <description>&lt;p&gt;Some time ago a headhunter from one of the biggest social networks in Russia contacted me and suggested an interview. I knew about their technical stack, however, and I declined the call since it’s not what I desired to deal with. &lt;/p&gt;

&lt;p&gt;To my surprise the headhunter said “yeah, but I believe that for a professional software engineer the toolset itself doesn’t matter”.&lt;/p&gt;

&lt;p&gt;Wow, that pissed me off, to put it lightly.&lt;/p&gt;

&lt;p&gt;Well, maybe I took it too personally and it harmed my fragile nerdy ego, but it wasn’t just that. &lt;/p&gt;

&lt;p&gt;From the beginning of my career in 2015 I always hear cool stories about T-Shaping, 10x-engineers and especially the requirement to be language-agnostic. At first glance there is nothing bad in any of it, especially being language-agnostic. &lt;/p&gt;

&lt;p&gt;You think that all you need is to learn high-level approaches and specific tools don’t matter. All lollipops and rainbows.&lt;/p&gt;

&lt;h3&gt;
  
  
  Choosing The Tool That Makes You More Productive
&lt;/h3&gt;

&lt;p&gt;The big gap here is that when you’re talking about being language-agnostic, no one mentions the productivity of a developer.  If I was a chef in a restaurant, it’s obvious that I would be more productive in serving good meals if I worked only with my own knives, my own tools.&lt;/p&gt;

&lt;p&gt;Why are software engineers in that case not the fortunate ones? &lt;/p&gt;

&lt;p&gt;Programming is also a craft, so let the craftsman choose the instruments they need to accomplish tasks.&lt;/p&gt;

&lt;p&gt;As a specialist, I’m really interested in solving specific and hard problems. I like challenges. Also I may prefer to work in specific business areas, like eCommerce, video-streaming, social networks, etc. &lt;/p&gt;

&lt;p&gt;You guessed it: For each specific problem there is a set of good tools.&lt;/p&gt;

&lt;p&gt;Developers work in teams. We’re not marathon runners - we are football players. And we get paid for things we deliver in specific infrastructure so there are a lot of reasons why we should use things we don’t like or we didn’t choose. Our employer or client chose them.&lt;/p&gt;

&lt;p&gt;However, You are not a bad engineer if you don’t want to appreciate a corporation's choice and while searching for a job you filter companies by their technological stack also.&lt;/p&gt;

&lt;p&gt;In fact, I think you might even be a better engineer and quite a visionary person, because you invest in your own future and carefully overcoming traps like maintaining someone else's legacy, which doesn’t develop you as a specialist. &lt;/p&gt;

&lt;h3&gt;
  
  
  Technology Agnostic Doesn’t Mean Forced Into Technology
&lt;/h3&gt;

&lt;p&gt;So let’s change the definition. For me, being technology-agnostic means being able to switch to a new more effective thing, but not accepting everything that is dictated to you.&lt;/p&gt;

&lt;p&gt;You are a specialist, you’ve got this mental model of what are pros and cons for each applied tool. As a specialist, share these insights with your current or potential employers without silent hating or hesitation.&lt;/p&gt;

&lt;p&gt;Businesses are interested in cheaper and faster hiring of new employees, thus preferring the most popular and the most mature technology. That’s fair, but you as a software engineer should also introduce an “effectiveness” variable into their equation.&lt;/p&gt;

&lt;p&gt;It is not only tools that I’m used to, maybe because I’m young and still “foolish and hungry”. &lt;/p&gt;

&lt;p&gt;It's easy to get stuck with a painful tool, because you've gotten used to this pain. &lt;/p&gt;

&lt;p&gt;I prefer tools that have an acceptable tradeoff between speed (including mine) and safety. In the last few years I’ve become a fan of limiting the ways to solve specific problems. For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Go provides simplistic features for concurrency and error-propagation.&lt;/li&gt;
&lt;li&gt;Rust has a borrow-checker that protects you from race-conditions and so on. &lt;/li&gt;
&lt;li&gt;And for me if a company has a monolithic technical stack, for example Java or .Net, there will always be cases where they don’t perform well and it’s a good point for experimenting.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;More and more, I hear stories when a company hires high-graded developers and gives them the freedom to solve problems with tools that they think are more appropriate. &lt;/p&gt;

&lt;p&gt;This is quite a sweet approach when companies have that kind of confidence in developer’s professionalism, that they don't care how the problem will be solved. I won’t lie, as a software engineer, I dream to be so good at my job that I can do just that.&lt;/p&gt;

&lt;p&gt;It’s quite valuable when a new software engineer brings improvements into a company's technical stack. This new blood can properly justify their decisions, when they consciously choose the technology - the tools that form them - during their career.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Code that writes code for you -wait what?</title>
      <dc:creator>dsvigir</dc:creator>
      <pubDate>Wed, 01 Sep 2021 09:45:28 +0000</pubDate>
      <link>https://forem.com/infobipdev/code-that-writes-code-for-you-wait-what-d35</link>
      <guid>https://forem.com/infobipdev/code-that-writes-code-for-you-wait-what-d35</guid>
      <description>&lt;p&gt;I've spent six years as a team leader and one of my responsibilities was performing technical job interviews with potential candidates for our team/company. Soon I've noticed a pattern. Candidates working with JAVA programming language were not using &lt;a href="https://projectlombok.org/"&gt;https://projectlombok.org/&lt;/a&gt; on their projects. Yes, I'm aware it doesn't qualify for the drama-of-the-year category, but this was quite a surprise for me. Projectlombok.org was such an integral part of my daily work, one of those simple life hacks you are happy to share. So why is this simple code-generator so important? Well, if you want to join the church-of-release-from-writing-boring-and-repetitive-code, keep reading!&lt;/p&gt;

&lt;h5&gt;
  
  
  Why would you want to use code-generator?
&lt;/h5&gt;

&lt;p&gt;Simply put, if you want to spend your coding time on something new and challenging, code-generator can save you time spent on repetitive (or boring, as some may refer to it) coding. This fact alone can certainly speed up development and benefit the project or company you're working for. But, as always, first there are some issues to deal with.&lt;/p&gt;

&lt;h4&gt;
  
  
  A matter of Trust
&lt;/h4&gt;

&lt;p&gt;&lt;em&gt;"I only trust code that I wrote, should I trust generated code? "&lt;/em&gt; (Unknown Developer)&lt;/p&gt;

&lt;p&gt;The idea of using code generation as a standard operating procedure within our team was first brought up in one of our meetings. We soon figured out that:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;We wanted to write our own code&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;We trusted our code more than some auto-generated sequence&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;We discussed our coding guidelines, the fact that we do not like how generated code look, how it might be hard to read and understand, it might break OOP principles, clean code principles and so on. Most of the issues we've had with code generators were trust related, and this lack of trust was the first obstacle we wanted to address.&lt;/p&gt;

&lt;p&gt;Since trust takes time, we decided that our first use case should be something simple. There are a lot of really good, simple and helpful code generators.&lt;br&gt;
This blog should help you understand why and when you should use code generators, give you some example how and where we use it and give you overview of some simple code generators that have different purposes.&lt;/p&gt;

&lt;p&gt;Reflecting on my experience and thinking about code generators seems to me that when and why to use it is highly dependent on what project are you working on, what programing language are you using, what are the use cases, how complex is part of code that you want to replace with generated code.&lt;/p&gt;
&lt;h4&gt;
  
  
  Where do I Start?
&lt;/h4&gt;

&lt;p&gt;Remember Project Lombok? Let's give you an overview and see how it can help you to avoid repetitive, boring and error prone coding.&lt;/p&gt;

&lt;p&gt;Let's say we want to implement simple immutable class that will represent Car. It could look something like this:&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;So, to achieve immutability, we needed to write constructor with null checks for fields that are not permitted to be null and get methods for each field. We also override toString, which is something we usually do to be able to print some instance of this class to get human readable data for logs, debugging and so on.&lt;/p&gt;

&lt;p&gt;This is something that needs to be done, but it is repetitive and boring, not to mention error prone. If we lose focus we could easily forget to add Object.requiredNonNull for field that must not be null. The bottom line is that we want to speed this up and let code generator do the writing for us.&lt;/p&gt;

&lt;p&gt;Now let's see how this class looks when we use Lombok:&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;It's easy to see that the amount of code we need to write is significantly lower, not to mention that the class looks cleaner, as we also removed a lot of boilerplate code. We really don't need it in in source file to know what this class contains - Lombok annotations will tell us that.&lt;/p&gt;

&lt;p&gt;What did Lombok annotations do for us:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;@RequiredArgsConstructor&lt;/em&gt; - generates constructor with all fields that have final modifier on them.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;@Getter&lt;/em&gt; - generate get method for all fields in class&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;@ToString&lt;/em&gt; - overrides toString method which will use all fields to generate String representation of this class&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This is just a small subset of what Lombok can do for us. However, one should be aware that Lombok does not generate new source code (new Car.java) and it doesn't replace anything in original Car.java It injects necessary code during compile time into bytecode of compiled Car.class. You can always decompile Car.class if you want to inspect what exactly Lombok generated.&lt;/p&gt;

&lt;h4&gt;
  
  
  Is there anything I shouldn't do with code-generator?
&lt;/h4&gt;

&lt;p&gt;Code generates can be really powerful. You could probably write most of the project code to be self-generated, and describe project using semantic needed for a code generator to generate project source code without writing a single line of project code yourself.&lt;/p&gt;

&lt;p&gt;It's easy to get carried away and spend your time thinking about projects you could do with code generator rather than finishing the existing ones. Do not auto generate everything that can be auto generated - start with tackling simple, repetitive and boring code sequences. Try and do proof of concept and see where does that lead you to.&lt;br&gt;
 &lt;br&gt;
Some general tips to go by which might point you into direction this is where I should not use code generation. If you are doing proof of concept or you are already using code generation for some time:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;If you find yourself in need to modify generated code&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If you find yourself in need to inspect generated code&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If you find yourself constantly working on code generator because it is lacking some features&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If maintenance of code generator is taking considerable time compared to gain&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h4&gt;
  
  
  PROs of using code generators
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Less errors&lt;/strong&gt; - code generators do not make mistakes. They will do their job and generated code will be the same no matter how many times they generate it. Code generator doesn't get tired and it doesn't lose focus like humans do.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Time saving&lt;/strong&gt; - generating code is fast, much faster than any human can write code. More repetitive tasks and code you need to write means more time you save using code generators.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Expected output&lt;/strong&gt; - generated code will always be the one you are expecting. Naming, coding principles, the way code works will be something that will be same no matter who is using it. If a code is written manually by different developers, this kind of consistency usually cannot be achieved.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Cool, I don't need to write this code again&lt;/strong&gt; - as developers, we often found ourselves writing similar code all over again. This can be really boring, and in the end we should have fun when writing code, and code generators can provide us extra time to write a more meaningful code.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h4&gt;
  
  
  CONs of using code generators.
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;We need to modify code generator again&lt;/strong&gt; - our code generator requires constant maintenance. We are finding new use cases for it and it is getting more convoluted and time consuming to maintain it.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Code generated is not optimized&lt;/strong&gt; - if your code and project needs to squeeze every bit of performance, then code generators might be obstacle. Usually, to optimize code for performance you do it manually, change architecture of code, maybe change order of code lines or just rewrite it completely. If your code is generated, this can be really hard to do, and could require extensive modification on code generator you are using or it just might not be possible.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Generated code is a mess&lt;/strong&gt; - although this technically goes into cons, this should not be your concern and you should not be worried about how the code looks. Code should be something that works for you, strictly utilitarian.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h4&gt;
  
  
  Simple code generation in our project
&lt;/h4&gt;

&lt;p&gt;Our project is microservice oriented so we have multiple instances of various services and uptime of those services is very important. We collect over 200 metrics data and constantly monitor what is the state of our system/services.&lt;/p&gt;

&lt;p&gt;Most of our metrics are custom made. As the number of metrics increased, we found our self spending a lot of time writing a code that collects metrics required for some feature we were working on.&lt;/p&gt;

&lt;p&gt;This was our scenario:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Writing repetitive and error prone code&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Writing it for almost every new feature we added&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It was boring and it was slowing us down&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Let's say now we want to implement a set of metrics that will count how many red and blue cars we sold:&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;This is how our base for code generation looks like. Here we used our custom defined annotations (@MetricSchema, @MetricCounter) as metadata that we needed as an input into code generator and our custom defined metric type(ResetableCounter).&lt;/p&gt;

&lt;p&gt;This is how part of our generated source code looks like:&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;This generated class will be used as our metric object when instanced to collect metric on our application. It has all that we need to start collecting and reporting this metric.&lt;br&gt;
We have static factory method that will help us to instance metrics and we have methods to increment, reset metrics and method to retrieve metric value.&lt;/p&gt;

&lt;p&gt;Next example shows us how to use this generated code to collect metrics:&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;We are using &lt;a href="https://github.com/jtwig/jtwig-core"&gt;https://github.com/jtwig/jtwig-core&lt;/a&gt; as a code templating engine, and this is how our template looks like. Without going into too much details about jtwig, this template allows us to generate CarMetric class from AbstractCarMetric. This is how we generate all the metric classes that we need.&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;This is relatively simple code generation. Considering that we are writing and collecting a lot of metrics on our project, we did this to release us from the need to write metrics ourselves.&lt;/p&gt;

&lt;h4&gt;
  
  
  Some Simple Code Generators
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://projectlombok.org/"&gt;https://projectlombok.org/&lt;/a&gt; — we discussed it earlier, it has a lot of functionality, most commonly used functionality is going to free you from writing repetitive boilerplate code (constructors, getters and setters and so on)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.jooq.org/doc/3.14/manual/code-generation/"&gt;https://www.jooq.org/doc/3.14/manual/code-generation/&lt;/a&gt; — this code generator is used in conjunction with library itself. Main job of this code generator is to inspect your database schema and generate classes that represent object model of your database. This is very common case for code generators as writing object model for database manually is very repetitive, error prone and time consuming.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://developers.google.com/protocol-buffers"&gt;https://developers.google.com/protocol-buffers&lt;/a&gt; — protocol buffers are usually used in conjunction with &lt;a href="https://grpc.io/docs/what-is-grpc/introduction/"&gt;https://grpc.io/docs/what-is-grpc/introduction/&lt;/a&gt; but they do not have to be used for that exclusively. This is example of language agnostic code generator that can generate code from defined protobuff semantic for different programing languages.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  An advice at the finish line — Start with baby steps
&lt;/h4&gt;

&lt;p&gt;Code generators are a broad and complex topic. It might not be clear where you should start with code generators because use cases for them are virtually endless. You might end up using code generator and walk into something that in the long run will be a really big burden for the project you are working on.&lt;/p&gt;

&lt;p&gt;If you are just starting to use code generators, start with baby steps. Find your simple use case (repetitive, boring, error prone coding), do your research and find if someone already solved your problem.&lt;/p&gt;

&lt;p&gt;When you decide on which code generator you are going to use and what use case you want to cover, do proof of concept for it and move forward from there. Choose wisely I hope this blog post will be of help on your coding path!&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
