<?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>DEV Community: Amit Shekhar</title>
    <description>The latest articles on DEV Community by Amit Shekhar (@amitiitbhu).</description>
    <link>https://dev.to/amitiitbhu</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%2Fuser%2Fprofile_image%2F18209%2Fc773a4c2-d6ca-4416-8478-4a4c36fae000.PNG</url>
      <title>DEV Community: Amit Shekhar</title>
      <link>https://dev.to/amitiitbhu</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/amitiitbhu"/>
    <language>en</language>
    <item>
      <title>KV Cache in LLMs</title>
      <dc:creator>Amit Shekhar</dc:creator>
      <pubDate>Fri, 27 Mar 2026 15:54:59 +0000</pubDate>
      <link>https://dev.to/amitiitbhu/kv-cache-in-llms-188</link>
      <guid>https://dev.to/amitiitbhu/kv-cache-in-llms-188</guid>
      <description>&lt;p&gt;I am &lt;strong&gt;Amit Shekhar&lt;/strong&gt;, Founder @ &lt;a href="https://outcomeschool.com" rel="noopener noreferrer"&gt;Outcome School&lt;/a&gt;, I have taught and mentored many developers, and their efforts landed them high-paying tech jobs, helped many tech companies in solving their unique problems, and created many open-source libraries being used by top companies. I am passionate about sharing knowledge through open-source, blogs, and videos.&lt;/p&gt;

&lt;p&gt;I teach &lt;strong&gt;AI and Machine Learning&lt;/strong&gt;, and &lt;strong&gt;Android&lt;/strong&gt; at Outcome School.&lt;/p&gt;

&lt;p&gt;Join &lt;strong&gt;Outcome School&lt;/strong&gt; and get high paying tech job:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://outcomeschool.com/program/ai-and-machine-learning" rel="noopener noreferrer"&gt;Outcome School AI and Machine Learning Program&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://outcomeschool.com/program/android" rel="noopener noreferrer"&gt;Outcome School Android Program&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In this blog, we will learn about &lt;strong&gt;KV Cache&lt;/strong&gt; - where K stands for Key and V stands for Value - and why it is used in Large Language Models (LLMs) to speed up text generation.&lt;/p&gt;

&lt;p&gt;We will start with how LLMs generate text one token at a time, understand the role of Key, Value, and Query inside the model, see the problem of repeated computation through an example, and then walk through how KV Cache solves this problem by storing and reusing past results.&lt;/p&gt;

&lt;p&gt;Let's get started.&lt;/p&gt;

&lt;h2&gt;
  
  
  How LLMs Generate Text
&lt;/h2&gt;

&lt;p&gt;Before we understand KV Cache, we first need to understand how LLMs generate text.&lt;/p&gt;

&lt;p&gt;An LLM - Large Language Model - is a model that has been trained on a massive amount of text data. It can understand and generate human language. When we give it a sentence, it predicts what comes next.&lt;/p&gt;

&lt;p&gt;LLMs generate text &lt;strong&gt;one token at a time&lt;/strong&gt;. A token is a small piece of text - it can be a word, part of a word, or even a single character. For simplicity, let's treat each word as one token.&lt;/p&gt;

&lt;p&gt;Let's say we give the model this input:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"I love"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The model looks at &lt;strong&gt;"I"&lt;/strong&gt; and &lt;strong&gt;"love"&lt;/strong&gt;, and predicts the next token: &lt;strong&gt;"teaching"&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Now the full sequence becomes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"I love teaching"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The model looks at &lt;strong&gt;"I"&lt;/strong&gt;, &lt;strong&gt;"love"&lt;/strong&gt;, and &lt;strong&gt;"teaching"&lt;/strong&gt;, and predicts the next token: &lt;strong&gt;"AI"&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Now the full sequence becomes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"I love teaching AI"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This process continues, one token at a time, until the model decides to stop.&lt;/p&gt;

&lt;p&gt;The important thing to notice here is: every time the model predicts a new token, it needs to look at &lt;strong&gt;all the previous tokens&lt;/strong&gt; to decide what comes next.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Happens Inside the Model
&lt;/h2&gt;

&lt;p&gt;Now, let's understand what happens inside the model when it generates each token.&lt;/p&gt;

&lt;p&gt;The model has a component called the &lt;strong&gt;attention layer&lt;/strong&gt;. The job of the attention layer is to help the model figure out which previous tokens are important for predicting the next token. Not all previous tokens are equally useful. Some matter more than others.&lt;/p&gt;

&lt;p&gt;Inside the attention layer, every token is converted into three things. Let's understand each of them with a simple analogy.&lt;/p&gt;

&lt;p&gt;Imagine a classroom where a new student joins and wants to find out who can help with a specific topic:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Query (Q)&lt;/strong&gt;: The new student's question - "Who here knows about this topic?" Every token being predicted gets a Query. It represents what the token is looking for.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Key (K)&lt;/strong&gt;: The name tag each existing student wears that says what they know - "I know about math" or "I know about science." Every previous token gets a Key. It describes what information that token holds.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Value (V)&lt;/strong&gt;: The actual notes each student has. Once the new student finds the right person using their name tag (Key), the notes (Value) are what they actually use. Every previous token gets a Value. It carries the actual information.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So, the current token uses its &lt;strong&gt;Query&lt;/strong&gt; to compare against the &lt;strong&gt;Keys&lt;/strong&gt; of all previous tokens. This comparison produces &lt;strong&gt;attention scores&lt;/strong&gt; - numbers that tell the model how much focus to give to each previous token. A higher score means that token is more relevant. A lower score means it is less relevant. The model then uses these scores to collect the &lt;strong&gt;Values&lt;/strong&gt; from the relevant tokens.&lt;/p&gt;

&lt;p&gt;This is how the attention layer works.&lt;/p&gt;

&lt;p&gt;Now, let's see the problem.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem: Repeated Computation
&lt;/h2&gt;

&lt;p&gt;Every time the model predicts the next token, it computes the Key, Value, and Query for &lt;strong&gt;all tokens in the sequence&lt;/strong&gt; - not just the new one.&lt;/p&gt;

&lt;p&gt;Let's see what happens step by step with our example:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1:&lt;/strong&gt; Input is &lt;strong&gt;"I love"&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The model computes Key, Value, and Query for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;"I"&lt;/li&gt;
&lt;li&gt;"love"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It uses these to predict the next token: &lt;strong&gt;"teaching"&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2:&lt;/strong&gt; Input is &lt;strong&gt;"I love teaching"&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The model computes Key, Value, and Query for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;"I" (already computed in Step 1, but computed again)&lt;/li&gt;
&lt;li&gt;"love" (already computed in Step 1, but computed again)&lt;/li&gt;
&lt;li&gt;"teaching" (new)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It uses these to predict the next token: &lt;strong&gt;"AI"&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 3:&lt;/strong&gt; Input is &lt;strong&gt;"I love teaching AI"&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The model computes Key, Value, and Query for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;"I" (already computed in Step 1 and Step 2, but computed again)&lt;/li&gt;
&lt;li&gt;"love" (already computed in Step 1 and Step 2, but computed again)&lt;/li&gt;
&lt;li&gt;"teaching" (already computed in Step 2, but computed again)&lt;/li&gt;
&lt;li&gt;"AI" (new)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Do you see the problem?&lt;/p&gt;

&lt;p&gt;The Key and Value for &lt;strong&gt;"I"&lt;/strong&gt; were computed in Step 1. But the model computes them again in Step 2, and again in Step 3. The same goes for &lt;strong&gt;"love"&lt;/strong&gt; and &lt;strong&gt;"teaching"&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The model is repeating the same work for tokens it has already seen.&lt;/strong&gt; This is wasted computation.&lt;/p&gt;

&lt;p&gt;As the sequence grows longer, this problem gets worse. If the model has already generated 100 tokens, then at the next step, it would recompute the Key and Value for all 100 previous tokens just to predict one new token. This makes text generation very slow.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Solution: KV Cache
&lt;/h2&gt;

&lt;p&gt;The idea behind &lt;strong&gt;KV Cache&lt;/strong&gt; is simple: &lt;strong&gt;compute the Key and Value for each token once, store them, and reuse them in every future step&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Think of it like taking notes. Imagine you are in a meeting. Every time someone new speaks, instead of asking all the previous speakers to repeat what they said, you simply read from your notes and only listen to the new speaker. The notes are your cache.&lt;/p&gt;

&lt;p&gt;Similarly, &lt;strong&gt;KV Cache&lt;/strong&gt; is a memory where we save the Key and Value of every token that has already been processed. This way, the model does not have to compute them again.&lt;/p&gt;

&lt;p&gt;Let's see how the same example works with KV Cache:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1:&lt;/strong&gt; Input is &lt;strong&gt;"I love"&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The model computes Key, Value, and Query for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;"I"&lt;/li&gt;
&lt;li&gt;"love"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It saves the Key and Value of &lt;strong&gt;"I"&lt;/strong&gt; and &lt;strong&gt;"love"&lt;/strong&gt; in the &lt;strong&gt;KV Cache&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;It uses these to predict the next token: &lt;strong&gt;"teaching"&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;KV Cache now contains:&lt;/strong&gt; Key and Value for "I", "love"&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2:&lt;/strong&gt; Input is only &lt;strong&gt;"teaching"&lt;/strong&gt; (only the new token)&lt;/p&gt;

&lt;p&gt;The model retrieves the Key and Value of &lt;strong&gt;"I"&lt;/strong&gt; and &lt;strong&gt;"love"&lt;/strong&gt; from the KV Cache. &lt;strong&gt;No recomputation needed.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It computes Key, Value, and Query only for the new token: &lt;strong&gt;"teaching"&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;It saves the Key and Value of &lt;strong&gt;"teaching"&lt;/strong&gt; in the KV Cache.&lt;/p&gt;

&lt;p&gt;It uses all of these together to predict the next token: &lt;strong&gt;"AI"&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;KV Cache now contains:&lt;/strong&gt; Key and Value for "I", "love", "teaching"&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 3:&lt;/strong&gt; Input is only &lt;strong&gt;"AI"&lt;/strong&gt; (only the new token)&lt;/p&gt;

&lt;p&gt;The model retrieves the Key and Value of &lt;strong&gt;"I"&lt;/strong&gt;, &lt;strong&gt;"love"&lt;/strong&gt;, and &lt;strong&gt;"teaching"&lt;/strong&gt; from the KV Cache. &lt;strong&gt;No recomputation needed.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It computes Key, Value, and Query only for the new token: &lt;strong&gt;"AI"&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;It saves the Key and Value of &lt;strong&gt;"AI"&lt;/strong&gt; in the KV Cache.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;KV Cache now contains:&lt;/strong&gt; Key and Value for "I", "love", "teaching", "AI"&lt;/p&gt;

&lt;p&gt;So, instead of recomputing the Key and Value for every token at every step, the model computes them only for the &lt;strong&gt;new token&lt;/strong&gt; and reuses the cached values for all previous tokens.&lt;/p&gt;

&lt;p&gt;This is how &lt;strong&gt;KV Cache&lt;/strong&gt; avoids repeated computation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Only Key and Value Are Cached, Not Query
&lt;/h2&gt;

&lt;p&gt;You would naturally ask: why do we cache only the Key and Value, and not the Query?&lt;/p&gt;

&lt;p&gt;The Query is only needed for the &lt;strong&gt;current token&lt;/strong&gt; - the one being generated right now. The current token uses its Query to compare against the Keys of all previous tokens to find which ones are relevant. Once the prediction is done, that Query is no longer needed.&lt;/p&gt;

&lt;p&gt;But the Key and Value of every past token are needed at &lt;strong&gt;every future step&lt;/strong&gt;, because every new token must look at all the previous tokens to make its prediction.&lt;/p&gt;

&lt;p&gt;So, we only need to store the Keys and Values. This is why it is called &lt;strong&gt;KV Cache&lt;/strong&gt; - it caches the &lt;strong&gt;K&lt;/strong&gt;eys and &lt;strong&gt;V&lt;/strong&gt;alues.&lt;/p&gt;

&lt;h2&gt;
  
  
  How Much Faster Does It Get
&lt;/h2&gt;

&lt;p&gt;Let's compare the two approaches side by side:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Without KV Cache:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Step 1: Compute K, V, Q for 2 tokens
Step 2: Compute K, V, Q for 3 tokens  (2 recomputed)
Step 3: Compute K, V, Q for 4 tokens  (3 recomputed)
Step 4: Compute K, V, Q for 5 tokens  (4 recomputed)
...
Step N: Compute K, V, Q for (N+1) tokens  (N recomputed)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The amount of computation keeps growing at every step.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;With KV Cache:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Step 1: Compute K, V, Q for 2 tokens → Save K, V for 2 tokens in cache
Step 2: Compute K, V, Q for 1 token  → Reuse K, V for 2 tokens from cache
Step 3: Compute K, V, Q for 1 token  → Reuse K, V for 3 tokens from cache
Step 4: Compute K, V, Q for 1 token  → Reuse K, V for 4 tokens from cache
...
Step N: Compute K, V, Q for 1 token  → Reuse K, V for N tokens from cache
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After the first step, the model computes only for &lt;strong&gt;one new token&lt;/strong&gt; at each step instead of the entire sequence.&lt;/p&gt;

&lt;p&gt;To put this into perspective: if the model is generating a sequence of 100 tokens, without KV Cache, the total number of Key and Value computations across all steps would be 2 + 3 + 4 + ... + 100 = &lt;strong&gt;5,049 computations&lt;/strong&gt;. With KV Cache, it would be 2 + 1 + 1 + ... + 1 = &lt;strong&gt;101 computations&lt;/strong&gt;. That is roughly &lt;strong&gt;50 times fewer computations&lt;/strong&gt;. The longer the sequence, the bigger the savings.&lt;/p&gt;

&lt;p&gt;This is what makes KV Cache so effective at speeding up text generation.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Trade-Off: Speed vs Memory
&lt;/h2&gt;

&lt;p&gt;KV Cache makes generation faster, but it comes with a trade-off: it uses extra memory to store all the Key and Value information for every token that has been generated so far.&lt;/p&gt;

&lt;p&gt;As the sequence gets longer, the cache grows larger. For very long sequences with thousands of tokens, the cache can consume a significant amount of memory.&lt;/p&gt;

&lt;p&gt;So, KV Cache is a trade-off: &lt;strong&gt;we use more memory to save computation time&lt;/strong&gt;. For most use cases, this trade-off is well worth it, as the speed improvement is significant.&lt;/p&gt;

&lt;p&gt;Now, we have understood the KV Cache in LLMs.&lt;/p&gt;

&lt;p&gt;In the next blog, we will learn about &lt;strong&gt;Paged Attention&lt;/strong&gt; that solves the memory issue of KV Cache.&lt;/p&gt;

&lt;p&gt;Prepare yourself for AI Engineering Interview: &lt;a href="https://github.com/amitshekhariitbhu/ai-engineering-interview-questions" rel="noopener noreferrer"&gt;AI Engineering Interview Questions&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That's it for now.&lt;/p&gt;

&lt;p&gt;Thanks&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Amit Shekhar&lt;/strong&gt;&lt;br&gt;
Founder @ &lt;a href="https://outcomeschool.com" rel="noopener noreferrer"&gt;Outcome School&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can connect with me on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://x.com/amitiitbhu" rel="noopener noreferrer"&gt;X&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.linkedin.com/in/amit-shekhar-iitbhu" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/@amitshekhar" rel="noopener noreferrer"&gt;YouTube&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/amitshekhariitbhu" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Follow Outcome School on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://x.com/outcome_school" rel="noopener noreferrer"&gt;X&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.linkedin.com/company/outcomeschool" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://youtube.com/@OutcomeSchool" rel="noopener noreferrer"&gt;YouTube&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://github.com/OutcomeSchool" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://outcomeschool.com/blog" rel="noopener noreferrer"&gt;&lt;strong&gt;Read all of our high-quality blogs here.&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>machinelearning</category>
      <category>ai</category>
    </item>
    <item>
      <title>Evolution of HTTP</title>
      <dc:creator>Amit Shekhar</dc:creator>
      <pubDate>Sun, 28 May 2023 06:51:03 +0000</pubDate>
      <link>https://dev.to/amitiitbhu/evolution-of-http-3hp7</link>
      <guid>https://dev.to/amitiitbhu/evolution-of-http-3hp7</guid>
      <description>&lt;p&gt;I am &lt;strong&gt;Amit Shekhar&lt;/strong&gt;, Co-Founder @ &lt;a href="https://outcomeschool.com" rel="noopener noreferrer"&gt;Outcome School&lt;/a&gt;, I have taught and mentored many developers, and their efforts landed them high-paying tech jobs, helped many tech companies in solving their unique problems, and created many open-source libraries being used by top companies. I am passionate about sharing knowledge through open-source, blogs, and videos.&lt;/p&gt;

&lt;p&gt;Before we start, I would like to mention that, I have released a video playlist to help you crack the Android Interview: Check out &lt;a href="https://www.youtube.com/playlist?list=PL_I3TGB7aK6jNBMZkw3FYdJXyf7quHdI8" rel="noopener noreferrer"&gt;Android Interview Questions and Answers&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In this blog, we will learn about the evolution of HTTP.&lt;/p&gt;

&lt;p&gt;HTTP has seen the following version in its evolution.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;HTTP 1.0&lt;/li&gt;
&lt;li&gt;HTTP 1.1&lt;/li&gt;
&lt;li&gt;HTTP 2.0&lt;/li&gt;
&lt;li&gt;HTTP 3.0&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;This article was originally published at &lt;a href="https://outcomeschool.com/blog/evolution-of-http" rel="noopener noreferrer"&gt;Outcome School&lt;/a&gt;.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Each version has some problems, and in order to get rid of those problems, it has to update itself. That's why HTTP kept on evolving like any other technology.&lt;/p&gt;

&lt;p&gt;So, we will discuss each of the versions of HTTP, the problem with that version, and how it got solved in the updated version.&lt;/p&gt;

&lt;p&gt;Let's start with HTTP 1.0&lt;/p&gt;

&lt;h2&gt;
  
  
  HTTP 1.0
&lt;/h2&gt;

&lt;p&gt;This was the first version of HTTP. It has a problem.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Problem&lt;/strong&gt;: Each request to the same server needed a new TCP connection.&lt;/p&gt;

&lt;p&gt;We needed a solution for that, and HTTP 1.1 was introduced to solve this problem.&lt;/p&gt;

&lt;h2&gt;
  
  
  HTTP 1.1
&lt;/h2&gt;

&lt;p&gt;It solves the HTTP 1.0 problem. But it has another problem.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Problem&lt;/strong&gt;: HOL blocking issue. HOL(head-of-line) blocking issue - new request had to wait for the earlier request to complete.&lt;/p&gt;

&lt;p&gt;HOL blocking issue at two layers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Application&lt;/li&gt;
&lt;li&gt;Transport(TCP)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Again, we needed a solution for that, and then HTTP 2.0 was released to solve this problem.&lt;/p&gt;

&lt;h2&gt;
  
  
  HTTP 2.0
&lt;/h2&gt;

&lt;p&gt;It solves the HTTP 1.1 problem of the HOL issue at the application layer using request multiplexing. But the HOL blocking issue at TCP was the problem.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Problem&lt;/strong&gt;: HOL blocking issue at TCP.&lt;/p&gt;

&lt;p&gt;And once again, we need a solution for that, and with the release of HTTP 3.0, this problem got solved.&lt;/p&gt;

&lt;h2&gt;
  
  
  HTTP 3.0
&lt;/h2&gt;

&lt;p&gt;It solves the HOL blocking issue at TCP. It uses QUIC(Quick UDP Internet Connections) which is based on UDP.&lt;/p&gt;

&lt;p&gt;This is how HTTP has evolved from HTTP 1.0 to HTTP 1.1 to HTTP 2.0 to HTTP 3.0.&lt;/p&gt;

&lt;p&gt;Master Kotlin Coroutines from here: &lt;a href="https://amitshekhar.me/blog/kotlin-coroutines" rel="noopener noreferrer"&gt;Mastering Kotlin Coroutines&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That's it for now.&lt;/p&gt;

&lt;p&gt;Thanks&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Amit Shekhar&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Co-Founder @ &lt;a href="https://outcomeschool.com" rel="noopener noreferrer"&gt;Outcome School&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can connect with me on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://twitter.com/amitiitbhu" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/@amitshekhar" rel="noopener noreferrer"&gt;YouTube&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.linkedin.com/in/amit-shekhar-iitbhu" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/amitshekhariitbhu" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://amitshekhar.me/blog" rel="noopener noreferrer"&gt;&lt;strong&gt;Read all of my high-quality blogs here.&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>backend</category>
      <category>http</category>
    </item>
    <item>
      <title>React Native vs Flutter</title>
      <dc:creator>Amit Shekhar</dc:creator>
      <pubDate>Mon, 22 May 2023 05:37:48 +0000</pubDate>
      <link>https://dev.to/amitiitbhu/react-native-vs-flutter-5ghn</link>
      <guid>https://dev.to/amitiitbhu/react-native-vs-flutter-5ghn</guid>
      <description>&lt;p&gt;I am &lt;strong&gt;Amit Shekhar&lt;/strong&gt;, Co-Founder @ &lt;a href="https://outcomeschool.com" rel="noopener noreferrer"&gt;Outcome School&lt;/a&gt;, I have taught and mentored many developers, and their efforts landed them high-paying tech jobs, helped many tech companies in solving their unique problems, and created many open-source libraries being used by top companies. I am passionate about sharing knowledge through open-source, blogs, and videos.&lt;/p&gt;

&lt;p&gt;Before we start, I would like to mention that, I have released a video playlist to help you crack the Android Interview: Check out &lt;a href="https://www.youtube.com/playlist?list=PL_I3TGB7aK6jNBMZkw3FYdJXyf7quHdI8" rel="noopener noreferrer"&gt;Android Interview Questions and Answers&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In this blog, we will learn about the difference between React Native and Flutter.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;This article was originally published at &lt;a href="https://outcomeschool.com/blog/react-native-vs-flutter" rel="noopener noreferrer"&gt;Outcome School&lt;/a&gt;.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Both React Native and Flutter are the two most popular cross-platform development frameworks. They both allow developers to create mobile apps using a single code base for both Android and iOS.&lt;/p&gt;

&lt;p&gt;When we are considering cross-platform development, we have both options. We need to choose one over the other. In order to choose one over the other, we must know the key differences between both frameworks.&lt;/p&gt;

&lt;p&gt;Let's start to learn about both of them. Starting with React Native.&lt;/p&gt;

&lt;h2&gt;
  
  
  React Native
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;React Native is a cross-platform framework created by Facebook.&lt;/li&gt;
&lt;li&gt;It is based on the JavaScript programming language. JavaScript is a widely-used language for web development.&lt;/li&gt;
&lt;li&gt;It uses the native UI components for both Android and iOS. It provides the native look which means different UI on Android and iOS, Android Native UI on Android, and iOS Native UI on iOS.&lt;/li&gt;
&lt;li&gt;Code Push: UI and business logic code (that we write in JavaScript for React Native Apps) can be updated simply through HTTP requests from the app directly without updating it on the Google Play Store / Apple App Store. This is a major advantage of React Native. You can push any new feature on the fly.&lt;/li&gt;
&lt;li&gt;App Size: React Native apps are relatively smaller as compared to Flutter apps.&lt;/li&gt;
&lt;li&gt;Performance: React Native uses a bridge to communicate JavaScript and native components, which is an overhead. It can have performance issues due to the bridge between JavaScript and native components. Hence, React Native is comparatively slower than Flutter.&lt;/li&gt;
&lt;li&gt;It is supported by a large community as it has been for so long time.&lt;/li&gt;
&lt;li&gt;It has a wide range of third-party libraries support.&lt;/li&gt;
&lt;li&gt;Web developers can start quickly as they already know JavaScript.&lt;/li&gt;
&lt;li&gt;Platform support: iOS, Android, Web.&lt;/li&gt;
&lt;li&gt;It is widely adopted.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now about the Flutter.&lt;/p&gt;

&lt;h2&gt;
  
  
  Flutter
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Flutter is a cross-platform framework created by Google.&lt;/li&gt;
&lt;li&gt;It is based on the Dart programming language, developed by Google specifically for building mobile and web apps.&lt;/li&gt;
&lt;li&gt;It uses its own rendering engine to create its own UI Components. So, it replaces the native platform UI components. It provides the same look on all the platforms.&lt;/li&gt;
&lt;li&gt;Code Push: Not supported. This is a major disadvantage of Flutter.&lt;/li&gt;
&lt;li&gt;App Size: Flutter apps are relatively larger as compared to React Native apps.&lt;/li&gt;
&lt;li&gt;Performance: Flutter is comparatively faster than React Native as it uses a rendering engine that directly renders to the platform, leading to fast and smooth animations.&lt;/li&gt;
&lt;li&gt;It is supported by a smaller community as compared to React Native. But growing rapidly.&lt;/li&gt;
&lt;li&gt;It has a small range of third-party libraries. But growing rapidly.&lt;/li&gt;
&lt;li&gt;It has a steeper learning curve as developers need to learn the Dart language.&lt;/li&gt;
&lt;li&gt;Platform support: iOS, Android, web, and other platforms like desktop(Windows, macOS, Linux) and embedded systems.&lt;/li&gt;
&lt;li&gt;It is not widely adopted but gaining popularity.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;From the above points, we have a good understanding of the difference between React Native and Flutter.&lt;/p&gt;

&lt;p&gt;Let me tabulate the differences between React Native and Flutter for your better understanding so that you can decide which one to use based on your use case.&lt;/p&gt;

&lt;h2&gt;
  
  
  React Native vs Flutter
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;React Native&lt;/th&gt;
&lt;th&gt;Flutter&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Language&lt;/td&gt;
&lt;td&gt;JavaScript.&lt;/td&gt;
&lt;td&gt;Dart.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;UI components&lt;/td&gt;
&lt;td&gt;Native UI components.&lt;/td&gt;
&lt;td&gt;Own UI Components.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Code Push&lt;/td&gt;
&lt;td&gt;Code Push supported.&lt;/td&gt;
&lt;td&gt;Code Push NOT supported.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;App Size&lt;/td&gt;
&lt;td&gt;Smaller App Size.&lt;/td&gt;
&lt;td&gt;Larger App Size.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Performance&lt;/td&gt;
&lt;td&gt;Comparatively slower.&lt;/td&gt;
&lt;td&gt;Comparatively faster.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Platform Support&lt;/td&gt;
&lt;td&gt;Platform support: iOS, Android, Web.&lt;/td&gt;
&lt;td&gt;Platform support: iOS, Android, web, and other platforms like desktop(Windows, macOS, Linux) and embedded systems.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Community Support&lt;/td&gt;
&lt;td&gt;Supported by a large community.&lt;/td&gt;
&lt;td&gt;Supported by a smaller community.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Now the big question: &lt;strong&gt;Which framework is right for you?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;There is no clear winner here, both React Native and Flutter have their pros and cons, and the right choice will depend on your experience, the goals, and the requirements of your project. You should consider the following factors:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Language&lt;/li&gt;
&lt;li&gt;UI Components&lt;/li&gt;
&lt;li&gt;Code Push&lt;/li&gt;
&lt;li&gt;App Size&lt;/li&gt;
&lt;li&gt;Performance&lt;/li&gt;
&lt;li&gt;Platform Support&lt;/li&gt;
&lt;li&gt;Community Support&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For example, React Native is a good choice if you need a code push feature so that you can update UI and business logic code on the fly without updating the apps on Google Play Store / Apple App Store.&lt;/p&gt;

&lt;p&gt;Another example: If you are a web developer, and you already know JavaScript, writing mobile apps in React Native is a no-brainer.&lt;/p&gt;

&lt;p&gt;With this, I will let you decide which cross-platform development framework is right for you.&lt;/p&gt;

&lt;p&gt;This was all about React Native vs Flutter.&lt;/p&gt;

&lt;p&gt;Master Kotlin Coroutines from here: &lt;a href="https://amitshekhar.me/blog/kotlin-coroutines" rel="noopener noreferrer"&gt;Mastering Kotlin Coroutines&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That's it for now.&lt;/p&gt;

&lt;p&gt;Thanks&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Amit Shekhar&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Co-Founder @ &lt;a href="https://outcomeschool.com" rel="noopener noreferrer"&gt;Outcome School&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can connect with me on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://twitter.com/amitiitbhu" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/@amitshekhar" rel="noopener noreferrer"&gt;YouTube&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.linkedin.com/in/amit-shekhar-iitbhu" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/amitshekhariitbhu" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://amitshekhar.me/blog" rel="noopener noreferrer"&gt;&lt;strong&gt;Read all of my high-quality blogs here.&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>android</category>
      <category>flutter</category>
      <category>ios</category>
    </item>
    <item>
      <title>Launch vs Async in Kotlin Coroutines</title>
      <dc:creator>Amit Shekhar</dc:creator>
      <pubDate>Thu, 16 Feb 2023 10:42:17 +0000</pubDate>
      <link>https://dev.to/amitiitbhu/launch-vs-async-in-kotlin-coroutines-49c4</link>
      <guid>https://dev.to/amitiitbhu/launch-vs-async-in-kotlin-coroutines-49c4</guid>
      <description>&lt;p&gt;I am &lt;strong&gt;Amit Shekhar&lt;/strong&gt;, Co-Founder @ &lt;a href="https://outcomeschool.com" rel="noopener noreferrer"&gt;Outcome School&lt;/a&gt;, I have taught and mentored many developers, and their efforts landed them high-paying tech jobs, helped many tech companies in solving their unique problems, and created many open-source libraries being used by top companies. I am passionate about sharing knowledge through open-source, blogs, and videos.&lt;/p&gt;

&lt;p&gt;Before we start, I would like to mention that, I have released a video playlist to help you crack the Android Interview: Check out &lt;a href="https://www.youtube.com/playlist?list=PL_I3TGB7aK6jNBMZkw3FYdJXyf7quHdI8" rel="noopener noreferrer"&gt;Android Interview Questions and Answers&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In this blog, we will learn about the Launch vs Async in Kotlin Coroutines. We will see how the Launch and Async differ from each other and when to use which one.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;This article was originally published at &lt;a href="https://outcomeschool.com/blog/launch-vs-async-in-kotlin-coroutines" rel="noopener noreferrer"&gt;Outcome School&lt;/a&gt;.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Let's get started.&lt;/p&gt;

&lt;p&gt;Both launch and async are the functions in Kotlin to start the Coroutines.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;launch{}&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;async{}&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The difference is that the &lt;code&gt;launch{}&lt;/code&gt; returns a &lt;code&gt;Job&lt;/code&gt; and does not carry any resulting value whereas the &lt;code&gt;async{}&lt;/code&gt; returns an instance of &lt;code&gt;Deferred&amp;lt;T&amp;gt;&lt;/code&gt;, which has an &lt;code&gt;await()&lt;/code&gt; function that returns the result of the coroutine like we have future in Java in which we do &lt;code&gt;future.get()&lt;/code&gt; to get the result.&lt;/p&gt;

&lt;p&gt;In other words:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;launch&lt;/strong&gt;: fire and forget.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;async&lt;/strong&gt;: perform a task and return a result.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let's take an example to learn launch vs async.&lt;/p&gt;

&lt;p&gt;We can use the &lt;code&gt;launch&lt;/code&gt; as below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;job&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;GlobalScope&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;launch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Dispatchers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Default&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// do something and do not return result&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It returns a job object which we can use to get a job's status or to cancel it.&lt;/p&gt;

&lt;p&gt;In the above example of launch, we have to do something and &lt;strong&gt;NOT&lt;/strong&gt; return the result back.&lt;/p&gt;

&lt;p&gt;But when we need the result back, we need to use the &lt;code&gt;async&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;deferredJob&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;GlobalScope&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;async&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Dispatchers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Default&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// do something and return result, for example 10 as a result&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="nd"&gt;@async&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;result&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;deferredJob&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;await&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c1"&gt;// result = 10&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, we get the result using the &lt;code&gt;await()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;In async also, we can use the &lt;code&gt;Deferred&lt;/code&gt; job object to get a job's status or to cancel it.&lt;/p&gt;

&lt;p&gt;Note: I have used GlobalScope for quick examples, we should avoid using it at all costs. In an Android project, we should use custom scopes based on our usecase such as &lt;code&gt;lifecycleScope&lt;/code&gt;, &lt;code&gt;viewModelScope&lt;/code&gt; and etc.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Another difference between launch and async is in terms of exception handling.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If any exception comes inside the &lt;strong&gt;launch&lt;/strong&gt; block, it crashes the application if we have not handled it.&lt;/p&gt;

&lt;p&gt;However, if any exception comes inside the async block, it is stored inside the resulting &lt;code&gt;Deferred&lt;/code&gt; and is not delivered anywhere else, it will get silently dropped unless we handle it.&lt;/p&gt;

&lt;p&gt;Let's understand this difference with code examples.&lt;/p&gt;

&lt;p&gt;Suppose we have a function that does something and throws an exception:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;doSomethingAndThrowException&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="nc"&gt;Exception&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Some Exception"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now using it with the &lt;strong&gt;launch&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="nc"&gt;GlobalScope&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;launch&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;doSomethingAndThrowException&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It will &lt;strong&gt;CRASH&lt;/strong&gt; the application as expected.&lt;/p&gt;

&lt;p&gt;We can handle it as below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="nc"&gt;GlobalScope&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;launch&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;doSomethingAndThrowException&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Exception&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// handle exception&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, the exception will come inside the catch block and we can handle it.&lt;/p&gt;

&lt;p&gt;And now, using it with the &lt;code&gt;async&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="nc"&gt;GlobalScope&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;async&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;doSomethingAndThrowException&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The application will &lt;strong&gt;NOT&lt;/strong&gt; crash. The exception will get dropped silently.&lt;/p&gt;

&lt;p&gt;Again, we can handle it as below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="nc"&gt;GlobalScope&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;async&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;doSomethingAndThrowException&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Exception&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// handle exception&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, the exception will come inside the catch block and we can handle it.&lt;/p&gt;

&lt;p&gt;Let me tabulate the difference between launch and async.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Launch&lt;/th&gt;
&lt;th&gt;Async&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Fire and forget.&lt;/td&gt;
&lt;td&gt;Perform a task and return a result.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;launch{}&lt;/code&gt; returns a &lt;code&gt;Job&lt;/code&gt; and does not carry any resulting value.&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;async{}&lt;/code&gt; returns an instance of &lt;code&gt;Deferred&amp;lt;T&amp;gt;&lt;/code&gt;, which has an &lt;code&gt;await()&lt;/code&gt; function that returns the result of the coroutine.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;If any exception comes inside the launch block, it crashes the application if we have not handled it.&lt;/td&gt;
&lt;td&gt;If any exception comes inside the async block, it is stored inside the resulting Deferred and is not delivered anywhere else, it will get silently dropped unless we handle it.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;So, we have understood the difference between the launch function and the async function.&lt;/p&gt;

&lt;p&gt;Master Kotlin Coroutines from here: &lt;a href="https://outcomeschool.com/blog/kotlin-coroutines" rel="noopener noreferrer"&gt;Mastering Kotlin Coroutines&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Outcome School Android Program: &lt;a href="https://outcomeschool.com/program/android" rel="noopener noreferrer"&gt;Outcome School Android Program&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That's it for now.&lt;/p&gt;

&lt;p&gt;Thanks&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Amit Shekhar&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Founder @ &lt;a href="https://outcomeschool.com" rel="noopener noreferrer"&gt;Outcome School&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can connect with me on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://twitter.com/amitiitbhu" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/@amitshekhar" rel="noopener noreferrer"&gt;YouTube&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.linkedin.com/in/amit-shekhar-iitbhu" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/amitshekhariitbhu" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://amitshekhar.me/blog" rel="noopener noreferrer"&gt;&lt;strong&gt;Read all of my high-quality blogs here.&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>kotlin</category>
      <category>android</category>
    </item>
    <item>
      <title>callbackFlow - Callback to Flow API in Kotlin</title>
      <dc:creator>Amit Shekhar</dc:creator>
      <pubDate>Tue, 31 Jan 2023 05:31:27 +0000</pubDate>
      <link>https://dev.to/amitiitbhu/callbackflow-callback-to-flow-api-in-kotlin-5fpm</link>
      <guid>https://dev.to/amitiitbhu/callbackflow-callback-to-flow-api-in-kotlin-5fpm</guid>
      <description>&lt;p&gt;I am &lt;strong&gt;Amit Shekhar&lt;/strong&gt;, Co-Founder @ &lt;a href="https://outcomeschool.com" rel="noopener noreferrer"&gt;Outcome School&lt;/a&gt;, I have taught and mentored many developers, and their efforts landed them high-paying tech jobs, helped many tech companies in solving their unique problems, and created many open-source libraries being used by top companies. I am passionate about sharing knowledge through open-source, blogs, and videos.&lt;/p&gt;

&lt;p&gt;Before we start, I would like to mention that, I have released a video playlist to help you crack the Android Interview: Check out &lt;a href="https://www.youtube.com/playlist?list=PL_I3TGB7aK6jNBMZkw3FYdJXyf7quHdI8" rel="noopener noreferrer"&gt;Android Interview Questions and Answers&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In this blog, we will learn how to convert any Callback to Flow API in Kotlin using callbackFlow.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;This article was originally published at &lt;a href="https://outcomeschool.com/blog/callback-to-flow-api-in-kotlin" rel="noopener noreferrer"&gt;Outcome School&lt;/a&gt;.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This blog is a part of the series I have written on &lt;strong&gt;Flow API in Kotlin&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://amitshekhar.me/blog/flow-api-in-kotlin" rel="noopener noreferrer"&gt;Mastering Flow API in Kotlin&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://amitshekhar.me/blog/creating-flow-using-flow-builder-in-kotlin" rel="noopener noreferrer"&gt;Creating Flow Using Flow Builder in Kotlin&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://amitshekhar.me/blog/terminal-operators-in-kotlin-flow" rel="noopener noreferrer"&gt;Terminal Operators in Kotlin Flow&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://amitshekhar.me/blog/cold-flow-vs-hot-flow" rel="noopener noreferrer"&gt;Cold Flow vs Hot Flow&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://amitshekhar.me/blog/stateflow-and-sharedflow" rel="noopener noreferrer"&gt;StateFlow and SharedFlow&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://amitshekhar.me/blog/long-running-tasks-in-parallel-with-kotlin-flow" rel="noopener noreferrer"&gt;Long-running tasks in parallel with Kotlin Flow&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://amitshekhar.me/blog/retry-operator-in-kotlin-flow" rel="noopener noreferrer"&gt;Retry Operator in Kotlin Flow&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://amitshekhar.me/blog/retrofit-with-kotlin-flow" rel="noopener noreferrer"&gt;Retrofit with Kotlin Flow&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://amitshekhar.me/blog/room-database-with-kotlin-flow" rel="noopener noreferrer"&gt;Room Database with Kotlin Flow&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://amitshekhar.me/blog/kotlin-flow-zip-operator-parallel-multiple-network-calls" rel="noopener noreferrer"&gt;Kotlin Flow Zip Operator for Parallel Multiple Network Calls&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://amitshekhar.me/blog/instant-search-using-kotlin-flow-operators" rel="noopener noreferrer"&gt;Instant Search Using Kotlin Flow Operators&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://amitshekhar.me/blog/exception-handling-in-kotlin-flow" rel="noopener noreferrer"&gt;Exception Handling in Kotlin Flow&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;callbackFlow - Callback to Flow API in Kotlin - &lt;strong&gt;YOU ARE HERE&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://amitshekhar.me/blog/unit-testing-viewmodel-with-kotlin-flow-and-stateflow" rel="noopener noreferrer"&gt;Unit Testing ViewModel with Kotlin Flow and StateFlow&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We use many libraries in our Android Project that provides the callback way to use instead of the Flow API way. As nowadays, we all have started using Kotlin Coroutines Flow API in our projects, so it becomes our responsibility to implement things in a way that supports Flow API.&lt;/p&gt;

&lt;p&gt;So, we need to learn how to convert any Callback to Flow API in Kotlin using callbackFlow. And, this is the topic of this blog.&lt;/p&gt;

&lt;p&gt;Here, I will take an example of a LocationManager just for the sake of understanding.&lt;/p&gt;

&lt;p&gt;Assume that we can use LocationManager and listen to the changes in location as below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="c1"&gt;// create a location listener&lt;/span&gt;
&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;locationListener&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;object&lt;/span&gt; &lt;span class="err"&gt;: &lt;/span&gt;&lt;span class="nc"&gt;LocationListener&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;onLocationUpdate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;location&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Location&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// do something with the updated location&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// register for location updates&lt;/span&gt;
&lt;span class="nc"&gt;LocationManager&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;registerForLocation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;locationListener&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;// unregister in onDestroy()&lt;/span&gt;
&lt;span class="nc"&gt;LocationManager&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;unregisterForLocation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;locationListener&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, we have a LocationListener through which we get the &lt;code&gt;onLocationUpdate&lt;/code&gt; callback.&lt;/p&gt;

&lt;p&gt;Now, we want to use this LocationManager in the Flow API way.&lt;/p&gt;

&lt;p&gt;Let's do this by creating a function which returns &lt;code&gt;Flow&amp;lt;Location&amp;gt;&lt;/code&gt; as below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;getLocationFlow&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="nc"&gt;Flow&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Location&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;callbackFlow&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

        &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;locationListener&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;object&lt;/span&gt; &lt;span class="err"&gt;: &lt;/span&gt;&lt;span class="nc"&gt;LocationListener&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

            &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;onLocationUpdate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;location&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Location&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="nf"&gt;trySend&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;location&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="nc"&gt;LocationManager&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;registerForLocation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;locationListener&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="nf"&gt;awaitClose&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nc"&gt;LocationManager&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;unregisterForLocation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;locationListener&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, it's time to understand what we have done to convert the Callback to Flow API.&lt;/p&gt;

&lt;p&gt;We have followed the following steps to convert the Callback to Flow API in Kotlin:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create a function to return the &lt;code&gt;Flow&amp;lt;Location&amp;gt;&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;callbackFlow&lt;/code&gt; as the return block.&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;trySend()&lt;/code&gt; for the location updates.&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;awaitClose&lt;/code&gt; block to unregister.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now, we can use the above function as below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="nf"&gt;launch&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;getLocationFlow&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;collect&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;location&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt;
        &lt;span class="c1"&gt;// do something with the updated location&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is how we can convert any callback to Flow API in Kotlin using callbackFlow.&lt;/p&gt;

&lt;p&gt;So, today we learned how to convert any callback to Flow API and use them.&lt;/p&gt;

&lt;p&gt;Master Kotlin Coroutines from here: &lt;a href="https://outcomeschool.com/blog/kotlin-coroutines" rel="noopener noreferrer"&gt;Mastering Kotlin Coroutines&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Outcome School Android Program: &lt;a href="https://outcomeschool.com/program/android" rel="noopener noreferrer"&gt;Outcome School Android Program&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That's it for now.&lt;/p&gt;

&lt;p&gt;Thanks&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Amit Shekhar&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Co-Founder @ &lt;a href="https://outcomeschool.com" rel="noopener noreferrer"&gt;Outcome School&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can connect with me on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://twitter.com/amitiitbhu" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/@amitshekhar" rel="noopener noreferrer"&gt;YouTube&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.linkedin.com/in/amit-shekhar-iitbhu" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/amitshekhariitbhu" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://amitshekhar.me/blog" rel="noopener noreferrer"&gt;&lt;strong&gt;Read all of my high-quality blogs here.&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>kotlin</category>
      <category>android</category>
    </item>
    <item>
      <title>Dalvik, ART, JIT, and AOT in Android</title>
      <dc:creator>Amit Shekhar</dc:creator>
      <pubDate>Fri, 27 Jan 2023 15:28:18 +0000</pubDate>
      <link>https://dev.to/amitiitbhu/dalvik-art-jit-and-aot-in-android-3eje</link>
      <guid>https://dev.to/amitiitbhu/dalvik-art-jit-and-aot-in-android-3eje</guid>
      <description>&lt;p&gt;I am &lt;strong&gt;Amit Shekhar&lt;/strong&gt;, Co-Founder @ &lt;a href="https://outcomeschool.com" rel="noopener noreferrer"&gt;Outcome School&lt;/a&gt;, I have taught and mentored many developers, and their efforts landed them high-paying tech jobs, helped many tech companies in solving their unique problems, and created many open-source libraries being used by top companies. I am passionate about sharing knowledge through open-source, blogs, and videos.&lt;/p&gt;

&lt;p&gt;Before we start, I would like to mention that, I have released a video playlist to help you crack the Android Interview: Check out &lt;a href="https://www.youtube.com/playlist?list=PL_I3TGB7aK6jNBMZkw3FYdJXyf7quHdI8" rel="noopener noreferrer"&gt;Android Interview Questions and Answers&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In this blog, we will learn about the terms Dalvik, ART, JIT, and AOT in Android.&lt;/p&gt;

&lt;p&gt;We, Android Developers keep hearing these terms when we talk about optimization, and performance but have little or no idea about them.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Dalvik&lt;/li&gt;
&lt;li&gt;ART&lt;/li&gt;
&lt;li&gt;JIT&lt;/li&gt;
&lt;li&gt;AOT&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Do not worry, today we will learn about each of them in detail.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;This article was originally published at &lt;a href="https://outcomeschool.com/blog/dalvik-art-jit-aot" rel="noopener noreferrer"&gt;Outcome School&lt;/a&gt;.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;These terms are related to Android Runtime, so first we must understand what is Android Runtime.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is Android Runtime?
&lt;/h3&gt;

&lt;p&gt;We write code in Kotlin/Java, and when we build the APK, it gets converted to bytecode.&lt;/p&gt;

&lt;p&gt;In our APK, we will have the .dex files that contain bytecode.&lt;/p&gt;

&lt;p&gt;Our Android devices can't run the bytecode directly, so it needs to be translated to the machine code. This translation is done by &lt;strong&gt;Android Runtime&lt;/strong&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Kotlin/Java &amp;gt; bytecode(.dex files in APK) &amp;gt; machine code&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So, now that we know what is Android Runtime, it's time to learn about the different types of Android Runtime and their evolution.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Dalvik&lt;/li&gt;
&lt;li&gt;ART&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let's first learn about the Dalvik.&lt;/p&gt;

&lt;h3&gt;
  
  
  Dalvik
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Dalvik&lt;/strong&gt;, our first Android Runtime is based on the &lt;strong&gt;JIT&lt;/strong&gt; compilation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;JIT&lt;/strong&gt; compilation means &lt;strong&gt;Just In Time&lt;/strong&gt; compilation.&lt;/p&gt;

&lt;p&gt;As the .dex contain the bytecode, it needs to be translated to the machine code to be run.&lt;/p&gt;

&lt;p&gt;In Dalvik Android Runtime, as it is JIT based, it gets translated when we run the app. As we keep on using the app, only that part of the bytecode gets converted to the machine code. Also, the most frequently used code gets cached so that we don't have to translate them again.&lt;/p&gt;

&lt;p&gt;This process is repeated every single time when we open the app using the CPU cycles and hence impacting the battery life.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Disadvantage&lt;/strong&gt;: Low performance and decreases battery performance.&lt;/p&gt;

&lt;p&gt;The performance of the application was not up to the mark as the translation was happening during the application run and it happens every time when we run the app.&lt;/p&gt;

&lt;p&gt;So, we needed a solution to make the apps more performant.&lt;/p&gt;

&lt;p&gt;In Android L, we were introduced to the new Android Runtime: &lt;strong&gt;ART&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Till now, we have learned about the &lt;strong&gt;Dalvik&lt;/strong&gt; and &lt;strong&gt;JIT&lt;/strong&gt;, now it's time to learn about the &lt;strong&gt;ART&lt;/strong&gt; and &lt;strong&gt;AOT&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  ART
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;ART&lt;/strong&gt;, our next Android Runtime is based on the &lt;strong&gt;AOT&lt;/strong&gt; compilation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;AOT&lt;/strong&gt; compilation means &lt;strong&gt;Ahead of Time&lt;/strong&gt; compilation.&lt;/p&gt;

&lt;p&gt;Again, as the .dex contain the bytecode, it needs to be translated to the machine code to be run.&lt;/p&gt;

&lt;p&gt;In ART Android Runtime, as it is AOT based, it gets translated before we run the app. It gets translated at the time of app installation only. Basically, when we install the app, it translates the bytecode into the machine code and stores it on the disk.&lt;/p&gt;

&lt;p&gt;So, by ART, the problem related to the low performance of Dalvik got solved. Now we have a high-performance application because there is no need for translation during the app run.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Advantage&lt;/strong&gt;: High Performance&lt;/p&gt;

&lt;p&gt;But, we should also talk about the disadvantages.&lt;/p&gt;

&lt;p&gt;One disadvantage is &lt;strong&gt;more installation time&lt;/strong&gt; as it translates the bytecode to the machine code at the time of app installation only.&lt;/p&gt;

&lt;p&gt;Another disadvantage of ART is that it needs &lt;strong&gt;more space&lt;/strong&gt; as it translates the bytecode into machine code and stores it on the disk. The pre-compiled binary occupies more space than the DEX bytecode. So, it takes more space as compared to the Dalvik runtime.&lt;/p&gt;

&lt;p&gt;The last disadvantage is that the &lt;strong&gt;boot time is more&lt;/strong&gt; as compared to the Dalvik as the cache is built during the boot. You might see an "Optimizing apps" dialog box while booting your Android devices.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Disadvantage&lt;/strong&gt;s:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;More install time&lt;/li&gt;
&lt;li&gt;More space on the disk&lt;/li&gt;
&lt;li&gt;More boot time&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Time to talk about the solution to these above-mentioned problems.&lt;/p&gt;

&lt;p&gt;Before that let's see the difference between Dalvik and ART in a tabular form.&lt;/p&gt;

&lt;h3&gt;
  
  
  Difference between Dalvik and ART
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Dalvik&lt;/th&gt;
&lt;th&gt;ART&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;JIT based&lt;/td&gt;
&lt;td&gt;AOT based&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Low performance&lt;/td&gt;
&lt;td&gt;High performance&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;More startup time&lt;/td&gt;
&lt;td&gt;Less startup time&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Less install time&lt;/td&gt;
&lt;td&gt;More install time&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Less space on the disk&lt;/td&gt;
&lt;td&gt;More space on the disk&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Less boot time&lt;/td&gt;
&lt;td&gt;More boot time&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Decreases battery performance&lt;/td&gt;
&lt;td&gt;Increases battery performance&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Does not have a better Garbage collection as compared to ART&lt;/td&gt;
&lt;td&gt;Better Garbage collection than Dalvik&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Now, let's get back to the discussion regarding the solution.&lt;/p&gt;

&lt;p&gt;And we all know that users use 20% of the Apps present on their devices 80% of the time. And also, 20% part of an application is used 80% of the time. So, it is unnecessary to keep the translation of the complete bytecode of all the apps. It's a complete waste of space and time.&lt;/p&gt;

&lt;p&gt;We could have a better solution.&lt;/p&gt;

&lt;p&gt;In Android N, &lt;strong&gt;Just In Time&lt;/strong&gt; compilation was introduced back with the &lt;strong&gt;profile-guided compilation&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Profile-guided compilation
&lt;/h3&gt;

&lt;p&gt;In profile-guided compilation, the translation is done using the &lt;strong&gt;Just In Time&lt;/strong&gt; compilation which means when we are using the app. Then, as it learns which part of the apps or which apps are being very frequently used, it caches the translated code for that part only and stores it on disk.&lt;/p&gt;

&lt;p&gt;This profile-guided compilation is hybrid &lt;strong&gt;ART with both JIT and AOT&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;In the initial few runs, the apps run slowly, but with the subsequent run, it becomes faster as it has learned more about the usage and has cached the translated code based on the usage.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Advantages&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Less install time&lt;/li&gt;
&lt;li&gt;Less space on the disk&lt;/li&gt;
&lt;li&gt;Less boot time&lt;/li&gt;
&lt;li&gt;Improved performance but only after the first few application usages.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Disadvantages&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Low performance in the initial few runs of the application.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now, that we have solved most of the issues, now we are left with only one issue which is "Low performance in the initial few runs of the application".&lt;/p&gt;

&lt;p&gt;We just need to solve this, and we will win.&lt;/p&gt;

&lt;p&gt;The solution: &lt;strong&gt;ART Cloud Profiles&lt;/strong&gt; that was introduced in Android P.&lt;/p&gt;

&lt;h3&gt;
  
  
  ART Cloud Profiles
&lt;/h3&gt;

&lt;p&gt;As we know that most of the apps are used in a similar pattern by most users, Google collects this usage pattern data about all the apps present on the Play Store. They aggregate the data and call it as "&lt;strong&gt;Code Profile&lt;/strong&gt;".&lt;/p&gt;

&lt;p&gt;This Code Profile has information about which part of the app is frequently run by most users.&lt;/p&gt;

&lt;p&gt;If we install an app, the Code Profile also gets downloaded along with the APK.&lt;/p&gt;

&lt;p&gt;ART uses it to translate the code that is frequently run by most users. It does it during the installation that is before the app run.&lt;/p&gt;

&lt;p&gt;And we start getting improved performance from the initial run of the application.&lt;/p&gt;

&lt;p&gt;All problems got solved.&lt;/p&gt;

&lt;p&gt;Master Kotlin Coroutines from here: &lt;a href="https://outcomeschool.com/blog/kotlin-coroutines" rel="noopener noreferrer"&gt;Mastering Kotlin Coroutines&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Outcome School Android Program: &lt;a href="https://outcomeschool.com/program/android" rel="noopener noreferrer"&gt;Outcome School Android Program&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That's it for now.&lt;/p&gt;

&lt;p&gt;Thanks&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Amit Shekhar&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Co-Founder @ &lt;a href="https://outcomeschool.com" rel="noopener noreferrer"&gt;Outcome School&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can connect with me on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://twitter.com/amitiitbhu" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/@amitshekhar" rel="noopener noreferrer"&gt;YouTube&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.linkedin.com/in/amit-shekhar-iitbhu" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/amitshekhariitbhu" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://amitshekhar.me/blog" rel="noopener noreferrer"&gt;&lt;strong&gt;Read all of my high-quality blogs here.&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>kotlin</category>
      <category>android</category>
    </item>
    <item>
      <title>Difference between == and === in Kotlin</title>
      <dc:creator>Amit Shekhar</dc:creator>
      <pubDate>Wed, 25 Jan 2023 06:57:51 +0000</pubDate>
      <link>https://dev.to/amitiitbhu/difference-between-and-in-kotlin-3ngb</link>
      <guid>https://dev.to/amitiitbhu/difference-between-and-in-kotlin-3ngb</guid>
      <description>&lt;p&gt;Hi, I am Amit Shekhar, Co-Founder @ &lt;a href="https://outcomeschool.com" rel="noopener noreferrer"&gt;Outcome School&lt;/a&gt; • IIT 2010-14 • I have taught and mentored many developers, and their efforts landed them high-paying tech jobs, helped many tech companies in solving their unique problems, and created many open-source libraries being used by top companies. I am passionate about sharing knowledge through open-source, blogs, and videos.&lt;/p&gt;

&lt;p&gt;Before we start, I would like to mention that, I have released a video playlist to help you crack the Android Interview: Check out &lt;a href="https://www.youtube.com/playlist?list=PL_I3TGB7aK6jNBMZkw3FYdJXyf7quHdI8" rel="noopener noreferrer"&gt;Android Interview Questions and Answers&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In this blog, we will learn about the difference between &lt;code&gt;==&lt;/code&gt; and &lt;code&gt;===&lt;/code&gt; in Kotlin.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;This article was originally published at &lt;a href="https://outcomeschool.com/blog/structural-and-referential-equality-in-kotlin" rel="noopener noreferrer"&gt;Outcome School&lt;/a&gt;.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In Kotlin, we have two types of equality:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Structural equality (&lt;code&gt;==&lt;/code&gt;): It checks for &lt;code&gt;equals()&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Referential equality (&lt;code&gt;===&lt;/code&gt;): It checks whether the two references point to the same object.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let's learn about these two equalities in Kotlin with examples.&lt;/p&gt;

&lt;p&gt;Suppose we have a class as below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Car&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note: This is NOT a data class. So, it will not implement the equals() method by default.&lt;/p&gt;

&lt;p&gt;First, let's first compare Structural equality.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;car1&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Car&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"RED"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;car2&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Car&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"BLUE"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;car1&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="n"&gt;car2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The output:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;It outputs false and it is obvious.&lt;/p&gt;

&lt;p&gt;Let's take another example.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;car1&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Car&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"RED"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;car2&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Car&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"RED"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;car1&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="n"&gt;car2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The output:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;It also outputs false even though the color of both cars is the same because we have not implemented the &lt;code&gt;equals()&lt;/code&gt; method.&lt;/p&gt;

&lt;p&gt;Let’s take another example.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;car1&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Car&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"RED"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;car2&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;car1&lt;/span&gt;
&lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;car1&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="n"&gt;car2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The output:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;It outputs true as the references to both objects are the same now, no need of checking for the &lt;code&gt;equals()&lt;/code&gt; method implementation.&lt;/p&gt;

&lt;p&gt;Now, compare Referential equality.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;car1&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Car&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"RED"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;car2&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Car&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"RED"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;car1&lt;/span&gt; &lt;span class="p"&gt;===&lt;/span&gt; &lt;span class="n"&gt;car2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The output:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;It outputs false as the references to both objects are different.&lt;/p&gt;

&lt;p&gt;Another example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;car1&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Car&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"RED"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;car2&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;car1&lt;/span&gt;
&lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;car1&lt;/span&gt; &lt;span class="p"&gt;===&lt;/span&gt; &lt;span class="n"&gt;car2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The output:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;It outputs true as the references to both objects are the same now.&lt;/p&gt;

&lt;p&gt;Till now, we have NOT implemented the &lt;code&gt;equals()&lt;/code&gt; method, there are two ways to implement &lt;code&gt;equals()&lt;/code&gt; method:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Making the class a data class.&lt;/li&gt;
&lt;li&gt;Adding our own &lt;code&gt;equals()&lt;/code&gt; method implementation.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Both will behave the same. So, let's go with the data class.&lt;/p&gt;

&lt;p&gt;As our class Car was not a data class. Now, let's make our class a data class.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;data class&lt;/span&gt; &lt;span class="nc"&gt;Car&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When we make it a data class, it implements &lt;code&gt;equals()&lt;/code&gt; method internally.&lt;/p&gt;

&lt;p&gt;Now, let's first compare Structural equality.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;car1&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Car&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"RED"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;car2&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Car&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"BLUE"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;car1&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="n"&gt;car2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The output:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;It outputs false that is obvious.&lt;/p&gt;

&lt;p&gt;Let's take another example.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;car1&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Car&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"RED"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;car2&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Car&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"RED"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;car1&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="n"&gt;car2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The output:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;It outputs true as the color of both cars is the same and we have made the class a data class that implements the &lt;code&gt;equals()&lt;/code&gt; method.&lt;/p&gt;

&lt;p&gt;Let’s take another example.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;car1&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Car&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"RED"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;car2&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;car1&lt;/span&gt;
&lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;car1&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="n"&gt;car2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The output:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;It outputs true as the references to both objects are the same now, no need of checking for the &lt;code&gt;equals()&lt;/code&gt; method implementation although it is a data class. The output will be the same even if it was not a data class as we have seen earlier.&lt;/p&gt;

&lt;p&gt;Now, compare Referential equality. It has no impact due to the data class.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;car1&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Car&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"RED"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;car2&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Car&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"RED"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;car1&lt;/span&gt; &lt;span class="p"&gt;===&lt;/span&gt; &lt;span class="n"&gt;car2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The output:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;It outputs false as the references to both objects are different.&lt;/p&gt;

&lt;p&gt;Another example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;car1&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Car&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"RED"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;car2&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;car1&lt;/span&gt;
&lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;car1&lt;/span&gt; &lt;span class="p"&gt;===&lt;/span&gt; &lt;span class="n"&gt;car2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The output:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;It outputs true as the references to both objects are the same now.&lt;/p&gt;

&lt;p&gt;Now, we know the difference between == and === in Kotlin.&lt;/p&gt;

&lt;p&gt;Watch the video format: &lt;a href="https://www.youtube.com/watch?v=lJtgxT2OIgQ" rel="noopener noreferrer"&gt;Difference between == and === in Kotlin&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Master Kotlin Coroutines from here: &lt;a href="https://outcomeschool.com/blog/kotlin-coroutines" rel="noopener noreferrer"&gt;Mastering Kotlin Coroutines&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Outcome School Android Program: &lt;a href="https://outcomeschool.com/program/android" rel="noopener noreferrer"&gt;Outcome School Android Program&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That's it for now.&lt;/p&gt;

&lt;p&gt;Thanks&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Amit Shekhar&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Co-Founder @ &lt;a href="https://outcomeschool.com" rel="noopener noreferrer"&gt;Outcome School&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can connect with me on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://twitter.com/amitiitbhu" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/@amitshekhar" rel="noopener noreferrer"&gt;YouTube&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.linkedin.com/in/amit-shekhar-iitbhu" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/amitshekhariitbhu" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://amitshekhar.me/blog" rel="noopener noreferrer"&gt;&lt;strong&gt;Read all of my high-quality blogs here.&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>kotlin</category>
      <category>android</category>
    </item>
    <item>
      <title>crossinline in Kotlin</title>
      <dc:creator>Amit Shekhar</dc:creator>
      <pubDate>Fri, 20 Jan 2023 06:25:14 +0000</pubDate>
      <link>https://dev.to/amitiitbhu/crossinline-in-kotlin-27m3</link>
      <guid>https://dev.to/amitiitbhu/crossinline-in-kotlin-27m3</guid>
      <description>&lt;p&gt;Hi, I am Amit Shekhar, Co-Founder @ &lt;a href="https://outcomeschool.com" rel="noopener noreferrer"&gt;Outcome School&lt;/a&gt; • IIT 2010-14 • I have taught and mentored many developers, and their efforts landed them high-paying tech jobs, helped many tech companies in solving their unique problems, and created many open-source libraries being used by top companies. I am passionate about sharing knowledge through open-source, blogs, and videos.&lt;/p&gt;

&lt;p&gt;Before we start, I would like to mention that, I have released a video playlist to help you crack the Android Interview: Check out &lt;a href="https://www.youtube.com/playlist?list=PL_I3TGB7aK6jNBMZkw3FYdJXyf7quHdI8" rel="noopener noreferrer"&gt;Android Interview Questions and Answers&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In this blog, we will learn about the &lt;code&gt;crossinline&lt;/code&gt; modifier in Kotlin.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;This article was originally published at &lt;a href="https://outcomeschool.com/blog/crossinline-in-kotlin" rel="noopener noreferrer"&gt;Outcome School&lt;/a&gt;.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;What is a &lt;code&gt;crossinline&lt;/code&gt; in Kotlin?&lt;/p&gt;

&lt;p&gt;&lt;code&gt;crossinline&lt;/code&gt; in Kotlin is used to avoid non-local returns.&lt;/p&gt;

&lt;p&gt;Do not worry about the term "non-local returns", we will learn it with an example.&lt;/p&gt;

&lt;p&gt;As we are learning about the &lt;code&gt;crossinline&lt;/code&gt;, we must be knowing about the &lt;code&gt;inline&lt;/code&gt; keyword in Kotlin. You can learn &lt;a href="https://amitshekhar.me/blog/inline-function-in-kotlin" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Let's take an example to understand the non-local returns.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;guide&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"guide start"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;teach&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"teach"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"guide end"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;inline&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;teach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;abc&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;Unit&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;abc&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, we have added a return statement in the lambda function that we are passing.&lt;/p&gt;

&lt;p&gt;Let's go to the decompiled code. The decompiled code is as below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;guide&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;print&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"guide start"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;print&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"teach"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When we notice the decompiled code, we find that there is no &lt;code&gt;System.out.print("guide end")&lt;/code&gt;. As we have added the &lt;strong&gt;return&lt;/strong&gt; inside the lambda, it allowed the &lt;strong&gt;non-local returns&lt;/strong&gt; and left the code below that.&lt;/p&gt;

&lt;p&gt;Now, we have an idea of non-local returns.&lt;/p&gt;

&lt;p&gt;How can we avoid this situation?&lt;/p&gt;

&lt;p&gt;&lt;code&gt;crossinline&lt;/code&gt; in Kotlin is the solution to avoid non-local returns.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;When we add the &lt;code&gt;crossinline&lt;/code&gt;, then it will not allow us the put the return inside that lambda.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Let's use the &lt;code&gt;crossinline&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Our updated code with &lt;code&gt;crossinline&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;guide&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"guide start"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;teach&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"teach"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="c1"&gt;// return is not allowed here&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"guide end"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;inline&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;teach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;crossinline&lt;/span&gt; &lt;span class="n"&gt;abc&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;Unit&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;abc&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Again, let's go to the decompiled code. The decompiled code is as below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;guide&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;print&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"guide start"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;print&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"teach"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;print&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"guide end"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, we can see that everything is as expected. We also have the &lt;code&gt;System.out.print("guide end")&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This is how the &lt;code&gt;crossinline&lt;/code&gt; can help us to avoid the "non-local returns".&lt;/p&gt;

&lt;p&gt;Now, we have understood the &lt;code&gt;crossinline&lt;/code&gt; in Kotlin.&lt;/p&gt;

&lt;p&gt;Learn about noinline: &lt;a href="https://amitshekhar.me/blog/noinline-in-kotlin" rel="noopener noreferrer"&gt;noinline in Kotlin&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Master Kotlin Coroutines from here: &lt;a href="https://amitshekhar.me/blog/kotlin-coroutines" rel="noopener noreferrer"&gt;Mastering Kotlin Coroutines&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That's it for now.&lt;/p&gt;

&lt;p&gt;Thanks&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Amit Shekhar&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Co-Founder @ &lt;a href="https://outcomeschool.com" rel="noopener noreferrer"&gt;Outcome School&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can connect with me on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://twitter.com/amitiitbhu" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/@amitshekhar" rel="noopener noreferrer"&gt;YouTube&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.linkedin.com/in/amit-shekhar-iitbhu" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/amitshekhariitbhu" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://amitshekhar.me/blog" rel="noopener noreferrer"&gt;&lt;strong&gt;Read all of my high-quality blogs here.&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>kotlin</category>
      <category>android</category>
    </item>
    <item>
      <title>noinline in Kotlin</title>
      <dc:creator>Amit Shekhar</dc:creator>
      <pubDate>Tue, 17 Jan 2023 05:40:57 +0000</pubDate>
      <link>https://dev.to/amitiitbhu/noinline-in-kotlin-5543</link>
      <guid>https://dev.to/amitiitbhu/noinline-in-kotlin-5543</guid>
      <description>&lt;p&gt;Hi, I am Amit Shekhar, Co-Founder @ &lt;a href="https://outcomeschool.com" rel="noopener noreferrer"&gt;Outcome School&lt;/a&gt; • IIT 2010-14 • I have taught and mentored many developers, and their efforts landed them high-paying tech jobs, helped many tech companies in solving their unique problems, and created many open-source libraries being used by top companies. I am passionate about sharing knowledge through open-source, blogs, and videos.&lt;/p&gt;

&lt;p&gt;Before we start, I would like to mention that, I have released a video playlist to help you crack the Android Interview: Check out &lt;a href="https://www.youtube.com/playlist?list=PL_I3TGB7aK6jNBMZkw3FYdJXyf7quHdI8" rel="noopener noreferrer"&gt;Android Interview Questions and Answers&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In this blog, we will learn about the &lt;code&gt;noinline&lt;/code&gt; modifier in Kotlin.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;This article was originally published at &lt;a href="https://outcomeschool.com/blog/noinline-in-kotlin" rel="noopener noreferrer"&gt;Outcome School&lt;/a&gt;.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;What is a &lt;code&gt;noinline&lt;/code&gt; in Kotlin?&lt;/p&gt;

&lt;p&gt;Assume that we do not want all of the lambdas passed to an &lt;code&gt;inline&lt;/code&gt; function to be inlined, in that case, we can mark those function parameters with the &lt;code&gt;noinline&lt;/code&gt; modifier.&lt;/p&gt;

&lt;p&gt;As we are learning about the &lt;code&gt;noinline&lt;/code&gt;, we must be knowing about the &lt;code&gt;inline&lt;/code&gt; keyword in Kotlin. You can learn &lt;a href="https://amitshekhar.me/blog/inline-function-in-kotlin" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Let's understand this &lt;code&gt;noinline&lt;/code&gt; modifier with an example.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;guide&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"guide start"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;teach&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"teach abc"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"teach xyz"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"guide end"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;inline&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;teach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;abc&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;Unit&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;xyz&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;Unit&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;abc&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="nf"&gt;xyz&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's go to the decompiled code. The decompiled code is as below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;guide&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;print&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"guide start"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;print&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"teach abc"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;print&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"teach xyz"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;print&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"guide end"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, both the lambdas(&lt;code&gt;abc&lt;/code&gt;, &lt;code&gt;xyz&lt;/code&gt;) passed to an inline function got inlined.&lt;/p&gt;

&lt;p&gt;What if we want only the first lambda(&lt;code&gt;abc&lt;/code&gt;) to get inlined but not the second lambda(&lt;code&gt;xyz&lt;/code&gt;)?&lt;/p&gt;

&lt;p&gt;In that case, we will have to use the &lt;code&gt;noinline&lt;/code&gt; modifier with that lambda(&lt;code&gt;xyz&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;Our updated code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;guide&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"guide start"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;teach&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"teach abc"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"teach xyz"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"guide end"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;inline&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;teach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;abc&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;Unit&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;noinline&lt;/span&gt; &lt;span class="n"&gt;xyz&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;Unit&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;abc&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="nf"&gt;xyz&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Again, let's go to the decompiled code. The decompiled code is as below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;guide&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;print&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"guide start"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;print&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"teach abc"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;teach&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Function&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nd"&gt;@Override&lt;/span&gt;
        &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;invoke&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;print&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"teach xyz"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;});&lt;/span&gt;
    &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;print&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"guide end"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;teach&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Function&lt;/span&gt; &lt;span class="n"&gt;xyz&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;xyz&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;invoke&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, we can see that the lambda(&lt;code&gt;xyz&lt;/code&gt;) has not got inlined as expected. Only the lambda(&lt;code&gt;abc&lt;/code&gt;) got inlined. This is how &lt;code&gt;noinline&lt;/code&gt; in Kotlin helped us in achieving what we wanted.&lt;/p&gt;

&lt;p&gt;This way, we used the &lt;code&gt;noinline&lt;/code&gt; to avoid the inlining.&lt;/p&gt;

&lt;p&gt;Now, we have understood the &lt;code&gt;noinline&lt;/code&gt; in Kotlin.&lt;/p&gt;

&lt;p&gt;Learn about crossinline: &lt;a href="https://amitshekhar.me/blog/crossinline-in-kotlin" rel="noopener noreferrer"&gt;crossinline in Kotlin&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Master Kotlin Coroutines from here: &lt;a href="https://amitshekhar.me/blog/kotlin-coroutines" rel="noopener noreferrer"&gt;Mastering Kotlin Coroutines&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That's it for now.&lt;/p&gt;

&lt;p&gt;Thanks&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Amit Shekhar&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Co-Founder @ &lt;a href="https://outcomeschool.com" rel="noopener noreferrer"&gt;Outcome School&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can connect with me on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://twitter.com/amitiitbhu" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/@amitshekhar" rel="noopener noreferrer"&gt;YouTube&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.linkedin.com/in/amit-shekhar-iitbhu" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/amitshekhariitbhu" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://amitshekhar.me/blog" rel="noopener noreferrer"&gt;&lt;strong&gt;Read all of my high-quality blogs here.&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>android</category>
      <category>kotlin</category>
    </item>
    <item>
      <title>Configuration with Viper in Go</title>
      <dc:creator>Amit Shekhar</dc:creator>
      <pubDate>Mon, 16 Jan 2023 13:46:14 +0000</pubDate>
      <link>https://dev.to/amitiitbhu/configuration-with-viper-in-go-3ec4</link>
      <guid>https://dev.to/amitiitbhu/configuration-with-viper-in-go-3ec4</guid>
      <description>&lt;p&gt;Hi, I am Amit Shekhar, Co-Founder @ &lt;a href="https://outcomeschool.com" rel="noopener noreferrer"&gt;Outcome School&lt;/a&gt; • IIT 2010-14 • I have taught and mentored many developers, and their efforts landed them high-paying tech jobs, helped many tech companies in solving their unique problems, and created many open-source libraries being used by top companies. I am passionate about sharing knowledge through open-source, blogs, and videos.&lt;/p&gt;

&lt;p&gt;In this blog, we will learn how to load the configurations from the envfile in Golang using Viper in Go (Golang) projects.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;This article was originally published at &lt;a href="https://outcomeschool.com/blog/configuration-with-viper-in-go" rel="noopener noreferrer"&gt;Outcome School&lt;/a&gt;.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;About the viper package&lt;/strong&gt;: Viper is used to find, load, and unmarshal a configuration file in JSON, TOML, YAML, HCL, INI, envfile, or Java properties formats.&lt;/p&gt;

&lt;p&gt;So, let's start learning to use this viper package to load configuration from the envfile in Go.&lt;/p&gt;

&lt;p&gt;I will be using the below-mentioned project for the implementation part. The project follows a clean architecture in Go Language. You can find the complete code for loading the configuration using the Viper package mentioned in the blog in the project itself.&lt;/p&gt;

&lt;p&gt;Link to the project: &lt;a href="https://github.com/amitshekhariitbhu/go-backend-clean-architecture" rel="noopener noreferrer"&gt;Go Backend Clean Architecture&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;As a first step, we should install the package:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;go get github.com/spf13/viper
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We have a &lt;code&gt;.env&lt;/code&gt; file in our project as below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;APP_ENV=development
SERVER_ADDRESS=:8080
PORT=8080
CONTEXT_TIMEOUT=2
DB_HOST=localhost
DB_PORT=27017
DB_USER=
DB_PASS=
DB_NAME=go-backend-clean-architecture-db
ACCESS_TOKEN_EXPIRY_HOUR = 2
REFRESH_TOKEN_EXPIRY_HOUR = 168
ACCESS_TOKEN_SECRET=access_token_secret
REFRESH_TOKEN_SECRET=refresh_token_secret
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And, we want to load the configuration from this &lt;code&gt;.env&lt;/code&gt; file.&lt;/p&gt;

&lt;p&gt;Now, we have to create a struct &lt;code&gt;Env&lt;/code&gt; in the &lt;code&gt;env.go&lt;/code&gt; file as below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;Env&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;AppEnv&lt;/span&gt;                 &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="s"&gt;`mapstructure:"APP_ENV"`&lt;/span&gt;
    &lt;span class="n"&gt;ServerAddress&lt;/span&gt;          &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="s"&gt;`mapstructure:"SERVER_ADDRESS"`&lt;/span&gt;
    &lt;span class="n"&gt;ContextTimeout&lt;/span&gt;         &lt;span class="kt"&gt;int&lt;/span&gt;    &lt;span class="s"&gt;`mapstructure:"CONTEXT_TIMEOUT"`&lt;/span&gt;
    &lt;span class="n"&gt;DBHost&lt;/span&gt;                 &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="s"&gt;`mapstructure:"DB_HOST"`&lt;/span&gt;
    &lt;span class="n"&gt;DBPort&lt;/span&gt;                 &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="s"&gt;`mapstructure:"DB_PORT"`&lt;/span&gt;
    &lt;span class="n"&gt;DBUser&lt;/span&gt;                 &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="s"&gt;`mapstructure:"DB_USER"`&lt;/span&gt;
    &lt;span class="n"&gt;DBPass&lt;/span&gt;                 &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="s"&gt;`mapstructure:"DB_PASS"`&lt;/span&gt;
    &lt;span class="n"&gt;DBName&lt;/span&gt;                 &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="s"&gt;`mapstructure:"DB_NAME"`&lt;/span&gt;
    &lt;span class="n"&gt;AccessTokenExpiryHour&lt;/span&gt;  &lt;span class="kt"&gt;int&lt;/span&gt;    &lt;span class="s"&gt;`mapstructure:"ACCESS_TOKEN_EXPIRY_HOUR"`&lt;/span&gt;
    &lt;span class="n"&gt;RefreshTokenExpiryHour&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;    &lt;span class="s"&gt;`mapstructure:"REFRESH_TOKEN_EXPIRY_HOUR"`&lt;/span&gt;
    &lt;span class="n"&gt;AccessTokenSecret&lt;/span&gt;      &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="s"&gt;`mapstructure:"ACCESS_TOKEN_SECRET"`&lt;/span&gt;
    &lt;span class="n"&gt;RefreshTokenSecret&lt;/span&gt;     &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="s"&gt;`mapstructure:"REFRESH_TOKEN_SECRET"`&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, create a function in the same &lt;code&gt;env.go&lt;/code&gt; file to load the &lt;code&gt;.env&lt;/code&gt; file and unmarshal it into the above created &lt;code&gt;Env&lt;/code&gt; struct.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;NewEnv&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;Env&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;env&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;Env&lt;/span&gt;&lt;span class="p"&gt;{}&lt;/span&gt;
    &lt;span class="n"&gt;viper&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SetConfigFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;".env"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;viper&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ReadInConfig&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Fatal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Can't find the file .env : "&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;viper&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Unmarshal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Fatal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Environment can't be loaded: "&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AppEnv&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s"&gt;"development"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"The App is running in development env"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;env&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, we can notice that we have provided the file &lt;code&gt;.env&lt;/code&gt; to the viper using the &lt;code&gt;SetConfigFile&lt;/code&gt; method, then read and finally unmarshal it into the &lt;code&gt;Env&lt;/code&gt; struct.&lt;/p&gt;

&lt;p&gt;The complete &lt;code&gt;env.go&lt;/code&gt; file will be as below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;bootstrap&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"log"&lt;/span&gt;

    &lt;span class="s"&gt;"github.com/spf13/viper"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;Env&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;AppEnv&lt;/span&gt;                 &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="s"&gt;`mapstructure:"APP_ENV"`&lt;/span&gt;
    &lt;span class="n"&gt;ServerAddress&lt;/span&gt;          &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="s"&gt;`mapstructure:"SERVER_ADDRESS"`&lt;/span&gt;
    &lt;span class="n"&gt;ContextTimeout&lt;/span&gt;         &lt;span class="kt"&gt;int&lt;/span&gt;    &lt;span class="s"&gt;`mapstructure:"CONTEXT_TIMEOUT"`&lt;/span&gt;
    &lt;span class="n"&gt;DBHost&lt;/span&gt;                 &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="s"&gt;`mapstructure:"DB_HOST"`&lt;/span&gt;
    &lt;span class="n"&gt;DBPort&lt;/span&gt;                 &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="s"&gt;`mapstructure:"DB_PORT"`&lt;/span&gt;
    &lt;span class="n"&gt;DBUser&lt;/span&gt;                 &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="s"&gt;`mapstructure:"DB_USER"`&lt;/span&gt;
    &lt;span class="n"&gt;DBPass&lt;/span&gt;                 &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="s"&gt;`mapstructure:"DB_PASS"`&lt;/span&gt;
    &lt;span class="n"&gt;DBName&lt;/span&gt;                 &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="s"&gt;`mapstructure:"DB_NAME"`&lt;/span&gt;
    &lt;span class="n"&gt;AccessTokenExpiryHour&lt;/span&gt;  &lt;span class="kt"&gt;int&lt;/span&gt;    &lt;span class="s"&gt;`mapstructure:"ACCESS_TOKEN_EXPIRY_HOUR"`&lt;/span&gt;
    &lt;span class="n"&gt;RefreshTokenExpiryHour&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;    &lt;span class="s"&gt;`mapstructure:"REFRESH_TOKEN_EXPIRY_HOUR"`&lt;/span&gt;
    &lt;span class="n"&gt;AccessTokenSecret&lt;/span&gt;      &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="s"&gt;`mapstructure:"ACCESS_TOKEN_SECRET"`&lt;/span&gt;
    &lt;span class="n"&gt;RefreshTokenSecret&lt;/span&gt;     &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="s"&gt;`mapstructure:"REFRESH_TOKEN_SECRET"`&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;NewEnv&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;Env&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;env&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;Env&lt;/span&gt;&lt;span class="p"&gt;{}&lt;/span&gt;
    &lt;span class="n"&gt;viper&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SetConfigFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;".env"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;viper&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ReadInConfig&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Fatal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Can't find the file .env : "&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;viper&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Unmarshal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Fatal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Environment can't be loaded: "&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AppEnv&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s"&gt;"development"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"The App is running in development env"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;env&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After that, we can just have the &lt;code&gt;Env&lt;/code&gt; as below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;env&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;NewEnv&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally, we can just access the configuration as below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;dbName&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DBName&lt;/span&gt;

&lt;span class="n"&gt;secret&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AccessTokenSecret&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So, this way we are able to access the configuration values.&lt;/p&gt;

&lt;p&gt;I will highly recommend going through the project and checking the usage of viper to load the configuration.&lt;/p&gt;

&lt;p&gt;Link to the project: &lt;a href="https://github.com/amitshekhariitbhu/go-backend-clean-architecture" rel="noopener noreferrer"&gt;Go Backend Clean Architecture&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This is how we can load the configurations from the envfile in Golang using Viper in Go (Golang) projects.&lt;/p&gt;

&lt;p&gt;Prepare yourself for Machine Learning Interview: &lt;a href="https://github.com/amitshekhariitbhu/machine-learning-interview-questions" rel="noopener noreferrer"&gt;Machine Learning Interview Questions&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That's it for now.&lt;/p&gt;

&lt;p&gt;Thanks&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Amit Shekhar&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Co-Founder @ &lt;a href="https://outcomeschool.com" rel="noopener noreferrer"&gt;Outcome School&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can connect with me on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://twitter.com/amitiitbhu" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/@amitshekhar" rel="noopener noreferrer"&gt;YouTube&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.linkedin.com/in/amit-shekhar-iitbhu" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/amitshekhariitbhu" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://outcomeschool.com/blog" rel="noopener noreferrer"&gt;&lt;strong&gt;Read all of our blogs here.&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>go</category>
      <category>backend</category>
    </item>
    <item>
      <title>Test with Testify and Mockery in Go</title>
      <dc:creator>Amit Shekhar</dc:creator>
      <pubDate>Mon, 16 Jan 2023 04:23:12 +0000</pubDate>
      <link>https://dev.to/amitiitbhu/test-with-testify-and-mockery-in-go-3gle</link>
      <guid>https://dev.to/amitiitbhu/test-with-testify-and-mockery-in-go-3gle</guid>
      <description>&lt;p&gt;Hi, I am Amit Shekhar, Co-Founder @ &lt;a href="https://outcomeschool.com" rel="noopener noreferrer"&gt;Outcome School&lt;/a&gt; • IIT 2010-14 • I have taught and mentored many developers, and their efforts landed them high-paying tech jobs, helped many tech companies in solving their unique problems, and created many open-source libraries being used by top companies. I am passionate about sharing knowledge through open-source, blogs, and videos.&lt;/p&gt;

&lt;p&gt;In this blog, we will learn about writing the unit test with Testify and Mockery in Go (Golang) project.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;This article was originally published at &lt;a href="https://outcomeschool.com/blog/test-with-testify-and-mockery-in-go" rel="noopener noreferrer"&gt;Outcome School&lt;/a&gt;.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;These two packages are very useful during the testing of any Go files.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;testify&lt;/strong&gt;: A toolkit with common assertions and mocks that plays nicely with the standard library.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;mockery&lt;/strong&gt;: A mock code autogenerator for Golang used in testing.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As we know that the testify package is used for the purpose of the assertions.&lt;/p&gt;

&lt;p&gt;mockery package provides the ability to easily generate mocks for Golang interfaces using the testify package. It removes the boilerplate coding required to use mocks.&lt;/p&gt;

&lt;p&gt;So, let's start learning to use both packages to write tests in Go.&lt;/p&gt;

&lt;p&gt;I will be using the below-mentioned project for the implementation part. The project follows a clean architecture in Go Language. You can find the complete code for unit testing using the Testify and Mockery mentioned in the blog in the project itself.&lt;/p&gt;

&lt;p&gt;Link to the project: &lt;a href="https://github.com/amitshekhariitbhu/go-backend-clean-architecture" rel="noopener noreferrer"&gt;Go Backend Clean Architecture&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In the project, we have Controller, Usecase, and Repository. In this blog, we will learn to write the test by taking the Usecase as an example.&lt;/p&gt;

&lt;p&gt;Consider the &lt;code&gt;TaskUsecase&lt;/code&gt; present inside the given project.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;usecase&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"context"&lt;/span&gt;
    &lt;span class="s"&gt;"time"&lt;/span&gt;

    &lt;span class="s"&gt;"github.com/amitshekhariitbhu/go-backend-clean-architecture/domain"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;taskUsecase&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;taskRepository&lt;/span&gt; &lt;span class="n"&gt;domain&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TaskRepository&lt;/span&gt;
    &lt;span class="n"&gt;contextTimeout&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Duration&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;NewTaskUsecase&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;taskRepository&lt;/span&gt; &lt;span class="n"&gt;domain&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TaskRepository&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;timeout&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Duration&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;domain&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TaskUsecase&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;taskUsecase&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;taskRepository&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;taskRepository&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;contextTimeout&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;timeout&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tu&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;taskUsecase&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;Create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;task&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;domain&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kt"&gt;error&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cancel&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WithTimeout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tu&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;contextTimeout&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;defer&lt;/span&gt; &lt;span class="n"&gt;cancel&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;tu&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;taskRepository&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;task&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tu&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;taskUsecase&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;FetchByUserID&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;userID&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;([]&lt;/span&gt;&lt;span class="n"&gt;domain&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cancel&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WithTimeout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tu&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;contextTimeout&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;defer&lt;/span&gt; &lt;span class="n"&gt;cancel&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;tu&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;taskRepository&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;FetchByUserID&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;userID&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So, our aim is to test the Usecase that is dependent on Repository. We will have to mock the Repository.&lt;/p&gt;

&lt;p&gt;As the mockery generates the mocks for Golang interfaces, suppose we have the following interface for the &lt;code&gt;TaskRepository&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;TaskRepository&lt;/span&gt; &lt;span class="k"&gt;interface&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;task&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kt"&gt;error&lt;/span&gt;
    &lt;span class="n"&gt;FetchByUserID&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;userID&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;([]&lt;/span&gt;&lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As a next step, we need to run the following command to generate the mock for this repository.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;mockery &lt;span class="nt"&gt;--dir&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;domain &lt;span class="nt"&gt;--output&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;domain/mocks &lt;span class="nt"&gt;--outpkg&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;mocks &lt;span class="nt"&gt;--all&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note: You will have to modify the command based on your project structure and directory.&lt;/p&gt;

&lt;p&gt;It should generate the &lt;code&gt;TaskRepository&lt;/code&gt; mock that we will be using for the testing.&lt;/p&gt;

&lt;p&gt;Now, that mock for the Repository is also ready, we can write the test for the Usecase.&lt;/p&gt;

&lt;p&gt;We will write the test for the &lt;code&gt;FetchByUserID&lt;/code&gt; method present in the Usecase.&lt;/p&gt;

&lt;p&gt;Here, we are testing two cases:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Success: The repository returns data successfully without any errors.&lt;/li&gt;
&lt;li&gt;Error: The repository returns an error.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The following is the code showing how to write those tests using the testify and mockery:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;usecase_test&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"context"&lt;/span&gt;
    &lt;span class="s"&gt;"errors"&lt;/span&gt;
    &lt;span class="s"&gt;"testing"&lt;/span&gt;
    &lt;span class="s"&gt;"time"&lt;/span&gt;

    &lt;span class="s"&gt;"github.com/amitshekhariitbhu/go-backend-clean-architecture/domain"&lt;/span&gt;
    &lt;span class="s"&gt;"github.com/amitshekhariitbhu/go-backend-clean-architecture/domain/mocks"&lt;/span&gt;
    &lt;span class="s"&gt;"github.com/amitshekhariitbhu/go-backend-clean-architecture/usecase"&lt;/span&gt;
    &lt;span class="s"&gt;"github.com/stretchr/testify/assert"&lt;/span&gt;
    &lt;span class="s"&gt;"github.com/stretchr/testify/mock"&lt;/span&gt;
    &lt;span class="s"&gt;"go.mongodb.org/mongo-driver/bson/primitive"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;TestFetchByUserID&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;testing&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;mockTaskRepository&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="nb"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;mocks&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TaskRepository&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;userObjectID&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;primitive&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewObjectID&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;userID&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;userObjectID&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Hex&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"success"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;testing&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

        &lt;span class="n"&gt;mockTask&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;domain&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;ID&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;     &lt;span class="n"&gt;primitive&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewObjectID&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
            &lt;span class="n"&gt;Title&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;  &lt;span class="s"&gt;"Test Title"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;UserID&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;userObjectID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="n"&gt;mockListTask&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="nb"&gt;make&lt;/span&gt;&lt;span class="p"&gt;([]&lt;/span&gt;&lt;span class="n"&gt;domain&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;mockListTask&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;mockListTask&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;mockTask&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="n"&gt;mockTaskRepository&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;On&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"FetchByUserID"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;mock&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Anything&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;userID&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Return&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;mockListTask&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Once&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

        &lt;span class="n"&gt;u&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;usecase&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewTaskUsecase&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;mockTaskRepository&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Second&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="n"&gt;list&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;FetchByUserID&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Background&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;userID&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="n"&gt;assert&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NoError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;assert&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NotNil&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;list&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;assert&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;list&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;mockListTask&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

        &lt;span class="n"&gt;mockTaskRepository&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AssertExpectations&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;

    &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"error"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;testing&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;mockTaskRepository&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;On&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"FetchByUserID"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;mock&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Anything&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;userID&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Return&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;errors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;New&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Unexpected"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Once&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

        &lt;span class="n"&gt;u&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;usecase&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewTaskUsecase&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;mockTaskRepository&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Second&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="n"&gt;list&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;FetchByUserID&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Background&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;userID&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="n"&gt;assert&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;assert&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Nil&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;list&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="n"&gt;mockTaskRepository&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AssertExpectations&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Case 1: Success&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In this case, we have mocked the method of Repository to return success with the data.&lt;/p&gt;

&lt;p&gt;Then, we are passing the mocked Repository into the Usecase.&lt;/p&gt;

&lt;p&gt;After that, we are calling the method of the Usecase.&lt;/p&gt;

&lt;p&gt;And then finally, asserting to check whether everything is as expected or not.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Case 2: Error&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In this case, we have mocked the method of Repository to return an error.&lt;/p&gt;

&lt;p&gt;Then, we are passing the mocked Repository into the Usecase.&lt;/p&gt;

&lt;p&gt;After that, we are calling the method of the Usecase.&lt;/p&gt;

&lt;p&gt;And then finally, asserting to check whether everything is as expected or not.&lt;/p&gt;

&lt;p&gt;Now, our test is ready to be run. We can run the test and check.&lt;/p&gt;

&lt;p&gt;We can run all the tests with the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;go&lt;/span&gt; &lt;span class="n"&gt;test&lt;/span&gt; &lt;span class="o"&gt;./...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is how we can write the unit test by using the Testify and Mockery package in Go (Golang) project.&lt;/p&gt;

&lt;p&gt;I will highly recommend going through the project and checking the tests written for the Controller, Usecase, and Repository.&lt;/p&gt;

&lt;p&gt;Link to the project: &lt;a href="https://github.com/amitshekhariitbhu/go-backend-clean-architecture" rel="noopener noreferrer"&gt;Go Backend Clean Architecture&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;That's it for now.&lt;/p&gt;

&lt;p&gt;Thanks&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Amit Shekhar&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Co-Founder @ &lt;a href="https://outcomeschool.com" rel="noopener noreferrer"&gt;Outcome School&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can connect with me on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://twitter.com/amitiitbhu" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/@amitshekhar" rel="noopener noreferrer"&gt;YouTube&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.linkedin.com/in/amit-shekhar-iitbhu" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/amitshekhariitbhu" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://amitshekhar.me/blog" rel="noopener noreferrer"&gt;&lt;strong&gt;Read all of my high-quality blogs here.&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>go</category>
      <category>test</category>
      <category>backend</category>
      <category>testing</category>
    </item>
    <item>
      <title>Go JWT Authentication Middleware</title>
      <dc:creator>Amit Shekhar</dc:creator>
      <pubDate>Wed, 11 Jan 2023 05:56:30 +0000</pubDate>
      <link>https://dev.to/amitiitbhu/go-jwt-authentication-middleware-3ha6</link>
      <guid>https://dev.to/amitiitbhu/go-jwt-authentication-middleware-3ha6</guid>
      <description>&lt;p&gt;Hi, I am Amit Shekhar, Co-Founder @ &lt;a href="https://outcomeschool.com" rel="noopener noreferrer"&gt;Outcome School&lt;/a&gt; • IIT 2010-14 • I have taught and mentored many developers, and their efforts landed them high-paying tech jobs, helped many tech companies in solving their unique problems, and created many open-source libraries being used by top companies. I am passionate about sharing knowledge through open-source, blogs, and videos.&lt;/p&gt;

&lt;p&gt;In this blog, we will learn the implementation of JWT Authentication Middleware in Go (Golang).&lt;/p&gt;

&lt;p&gt;First of all, I must mention that the use of JWT(JSON Web Token) in the OAuth 2.0 protocol is a battle-tested way of authenticating users.&lt;/p&gt;

&lt;p&gt;While most of the token-based authentication implementation needs a database query to verify the validity of the granted token, JWT doesn't need the database query to verify. Moreover, with JWT, we can encode some data like User ID as a payload and can be decoded to get the data when needed.&lt;/p&gt;

&lt;p&gt;We all have been using it for a long time in projects with different languages like Java, JavaScript, Python, etc. Today, we are going to do the same in the Go language.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;This article was originally published at &lt;a href="https://outcomeschool.com/blog/go-jwt-authentication-middleware" rel="noopener noreferrer"&gt;Outcome School&lt;/a&gt;.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Let's Go :)&lt;/p&gt;

&lt;p&gt;I will be using the below-mentioned project for the implementation part. The project follows a clean architecture in Go Language. You can find the complete code for the implementation of JWT Authentication Middleware mentioned in the blog in the project itself.&lt;/p&gt;

&lt;p&gt;Link to the project: &lt;a href="https://github.com/amitshekhariitbhu/go-backend-clean-architecture" rel="noopener noreferrer"&gt;Go Backend Clean Architecture&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;We will be using the following package to use JWT in Go:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;go get &lt;span class="nt"&gt;-u&lt;/span&gt; github.com/golang-jwt/jwt/v4
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, import it in your code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="s"&gt;"github.com/golang-jwt/jwt/v4"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;First of all, we have to create a file &lt;code&gt;jwt_custom.go&lt;/code&gt; in the domain package as below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;domain&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"github.com/golang-jwt/jwt/v4"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;JwtCustomClaims&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Name&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="s"&gt;`json:"name"`&lt;/span&gt;
    &lt;span class="n"&gt;ID&lt;/span&gt;   &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="s"&gt;`json:"id"`&lt;/span&gt;
    &lt;span class="n"&gt;jwt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StandardClaims&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;JwtCustomRefreshClaims&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;ID&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="s"&gt;`json:"id"`&lt;/span&gt;
    &lt;span class="n"&gt;jwt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StandardClaims&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and suppose, we have a struct &lt;code&gt;User&lt;/code&gt; as below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;domain&lt;/span&gt;

&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;User&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;ID&lt;/span&gt;       &lt;span class="kt"&gt;string&lt;/span&gt;
    &lt;span class="n"&gt;Name&lt;/span&gt;     &lt;span class="kt"&gt;string&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We also have to put the secret key and expiry time for both the access token and refresh token in our configuration files such as &lt;code&gt;.env&lt;/code&gt; or &lt;code&gt;config.json&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ACCESS_TOKEN_EXPIRY_HOUR &lt;span class="o"&gt;=&lt;/span&gt; 2
REFRESH_TOKEN_EXPIRY_HOUR &lt;span class="o"&gt;=&lt;/span&gt; 168
&lt;span class="nv"&gt;ACCESS_TOKEN_SECRET&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;access_token_secret
&lt;span class="nv"&gt;REFRESH_TOKEN_SECRET&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;refresh_token_secret
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I have used the &lt;code&gt;.env&lt;/code&gt; file for this and then loads it into the struct &lt;code&gt;Env&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;Env&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;AccessTokenExpiryHour&lt;/span&gt;  &lt;span class="kt"&gt;int&lt;/span&gt;
    &lt;span class="n"&gt;RefreshTokenExpiryHour&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;
    &lt;span class="n"&gt;AccessTokenSecret&lt;/span&gt;      &lt;span class="kt"&gt;string&lt;/span&gt;
    &lt;span class="n"&gt;RefreshTokenSecret&lt;/span&gt;     &lt;span class="kt"&gt;string&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, we have to create a file &lt;code&gt;tokenutil.go&lt;/code&gt;. I have created this inside the tokenutil package under the internal package.&lt;/p&gt;

&lt;p&gt;In this file, we have the following functions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;CreateAccessToken(user *domain.User, secret string, expiry int)&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;CreateRefreshToken(user *domain.User, secret string, expiry int)&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;IsAuthorized(requestToken string, secret string)&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ExtractIDFromToken(requestToken string, secret string)&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let's understand what these functions do one by one.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;CreateAccessToken(user *domain.User, secret string, expiry int)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This function takes three parameters: user, access secret, and expiry.&lt;/p&gt;

&lt;p&gt;And it creates a token by encoding the payload that consists of the user &lt;code&gt;Name&lt;/code&gt; and &lt;code&gt;ID&lt;/code&gt; with the given expiry time signed with the given access secret.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;CreateRefreshToken(user *domain.User, secret string, expiry int)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This function also takes three parameters: user, refresh secret, and expiry.&lt;/p&gt;

&lt;p&gt;And it creates a token by encoding the payload that consists of the user &lt;code&gt;ID&lt;/code&gt; with the given expiry time signed with the given refresh secret.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;IsAuthorized(requestToken string, secret string)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This function does the task of checking if the given token is authorized or not. That's it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;ExtractIDFromToken(requestToken string, secret string)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This function decodes and extracts the &lt;code&gt;ID&lt;/code&gt; that was encoded while creating the token.&lt;/p&gt;

&lt;p&gt;The complete code is present inside this &lt;code&gt;tokenutil.go&lt;/code&gt; file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;tokenutil&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"fmt"&lt;/span&gt;
    &lt;span class="s"&gt;"time"&lt;/span&gt;

    &lt;span class="s"&gt;"github.com/amitshekhariitbhu/go-backend-clean-architecture/domain"&lt;/span&gt;
    &lt;span class="n"&gt;jwt&lt;/span&gt; &lt;span class="s"&gt;"github.com/golang-jwt/jwt/v4"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;CreateAccessToken&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;domain&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;secret&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;expiry&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;accessToken&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="kt"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;exp&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Now&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Hour&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Duration&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;expiry&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Unix&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;claims&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;domain&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;JwtCustomClaims&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;Name&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;ID&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;   &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;StandardClaims&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;jwt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StandardClaims&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;ExpiresAt&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;exp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;token&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;jwt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewWithClaims&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;jwt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SigningMethodHS256&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;claims&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SignedString&lt;/span&gt;&lt;span class="p"&gt;([]&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;secret&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;CreateRefreshToken&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;domain&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;secret&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;expiry&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;refreshToken&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="kt"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;claimsRefresh&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;domain&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;JwtCustomRefreshClaims&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;ID&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;StandardClaims&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;jwt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StandardClaims&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;ExpiresAt&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Now&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Hour&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Duration&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;expiry&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Unix&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;token&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;jwt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewWithClaims&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;jwt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SigningMethodHS256&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;claimsRefresh&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;rt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SignedString&lt;/span&gt;&lt;span class="p"&gt;([]&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;secret&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;rt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;IsAuthorized&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;requestToken&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;secret&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;jwt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;requestToken&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;token&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;jwt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Token&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;interface&lt;/span&gt;&lt;span class="p"&gt;{},&lt;/span&gt; &lt;span class="kt"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ok&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Method&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;jwt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SigningMethodHMAC&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;ok&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Errorf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Unexpected signing method: %v"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Header&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"alg"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;secret&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="no"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="no"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;ExtractIDFromToken&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;requestToken&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;secret&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;jwt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;requestToken&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;token&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;jwt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Token&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;interface&lt;/span&gt;&lt;span class="p"&gt;{},&lt;/span&gt; &lt;span class="kt"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ok&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Method&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;jwt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SigningMethodHMAC&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;ok&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Errorf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Unexpected signing method: %v"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Header&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"alg"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;secret&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;claims&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ok&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Claims&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;jwt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MapClaims&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;ok&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Valid&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Errorf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Invalid Token"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;claims&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, we will create the middleware package. In this, we will create &lt;code&gt;jwt_auth_middleware.go&lt;/code&gt; file.&lt;/p&gt;

&lt;p&gt;Here, we need to understand that, based on the HTTP web framework that we are using, we will put the handler function corresponding to that framework. In our case, we are using the Gin HTTP web framework. So we will use the &lt;code&gt;gin.HandlerFunc&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;But the logic will be the same inside that function whatever framework we choose except the modification related to that framework.&lt;/p&gt;

&lt;p&gt;The code in that file will be as below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;middleware&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"net/http"&lt;/span&gt;
    &lt;span class="s"&gt;"strings"&lt;/span&gt;

    &lt;span class="s"&gt;"github.com/amitshekhariitbhu/go-backend-clean-architecture/domain"&lt;/span&gt;
    &lt;span class="s"&gt;"github.com/amitshekhariitbhu/go-backend-clean-architecture/internal/tokenutil"&lt;/span&gt;
    &lt;span class="s"&gt;"github.com/gin-gonic/gin"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;JwtAuthMiddleware&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;secret&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;gin&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;HandlerFunc&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;gin&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;authHeader&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Request&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Header&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Authorization"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;strings&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;authHeader&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;" "&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;authToken&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
            &lt;span class="n"&gt;authorized&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;tokenutil&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IsAuthorized&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;authToken&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;secret&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;authorized&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;userID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;tokenutil&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ExtractIDFromToken&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;authToken&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;secret&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StatusUnauthorized&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;domain&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ErrorResponse&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;Message&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;()})&lt;/span&gt;
                    &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Abort&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
                    &lt;span class="k"&gt;return&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;
                &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"x-user-id"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;userID&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Next&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
                &lt;span class="k"&gt;return&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StatusUnauthorized&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;domain&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ErrorResponse&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;Message&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;()})&lt;/span&gt;
            &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Abort&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StatusUnauthorized&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;domain&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ErrorResponse&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;Message&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Not authorized"&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
        &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Abort&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It takes the access secret key as an input parameter.&lt;/p&gt;

&lt;p&gt;First, it extracts the token from the header of the request.&lt;/p&gt;

&lt;p&gt;Then, it checks if the token is authorized or not, and it returns an error if not authorized.&lt;/p&gt;

&lt;p&gt;If it is authorized, it extracts the &lt;code&gt;UserID&lt;/code&gt; from the token that we have put in while creating the access token. And then put it into the context of the HTTP web framework used so that we can extract it easily when needed later in the request flow.&lt;/p&gt;

&lt;p&gt;We can get the &lt;code&gt;UserID&lt;/code&gt; from the HTTP Web Framework Context as below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;userID&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"x-user-id"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, we can use this middleware as below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;router&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;middleware&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;JwtAuthMiddleware&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AccessTokenSecret&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When we want to generate the access token, we can call:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;accessToken&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;tokenutil&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CreateAccessToken&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;secret&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;expiry&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For generating the refresh token, we can call:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;refreshToken&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;tokenutil&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CreateRefreshToken&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;secret&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;expiry&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is how we can use JWT Authentication Middleware in Go (Golang).&lt;/p&gt;

&lt;p&gt;I will highly recommend going through the project and checking the end-to-end flow of the implementation of JWT Authentication Middleware.&lt;/p&gt;

&lt;p&gt;Link to the project: &lt;a href="https://github.com/amitshekhariitbhu/go-backend-clean-architecture" rel="noopener noreferrer"&gt;Go Backend Clean Architecture&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Prepare yourself for Machine Learning Interview: &lt;a href="https://github.com/amitshekhariitbhu/machine-learning-interview-questions" rel="noopener noreferrer"&gt;Machine Learning Interview Questions&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That's it for now.&lt;/p&gt;

&lt;p&gt;Thanks&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Amit Shekhar&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Co-Founder @ &lt;a href="https://outcomeschool.com" rel="noopener noreferrer"&gt;Outcome School&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can connect with me on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://twitter.com/amitiitbhu" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/@amitshekhar" rel="noopener noreferrer"&gt;YouTube&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.linkedin.com/in/amit-shekhar-iitbhu" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/amitshekhariitbhu" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://outcomeschool.com/blog" rel="noopener noreferrer"&gt;&lt;strong&gt;Read all of our blogs here.&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>go</category>
      <category>jwt</category>
      <category>backend</category>
    </item>
  </channel>
</rss>
