<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Santosh Kumar</title>
    <description>The latest articles on Forem by Santosh Kumar (@santosh).</description>
    <link>https://forem.com/santosh</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%2F81385%2F6df09095-34ab-45e9-a633-0dbf29530bd2.jpeg</url>
      <title>Forem: Santosh Kumar</title>
      <link>https://forem.com/santosh</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/santosh"/>
    <language>en</language>
    <item>
      <title>__str__ vs __repr__ in Python and When to Use Them</title>
      <dc:creator>Santosh Kumar</dc:creator>
      <pubDate>Fri, 24 Feb 2023 18:30:00 +0000</pubDate>
      <link>https://forem.com/santosh/str-vs-repr-in-python-and-when-to-use-them-58e5</link>
      <guid>https://forem.com/santosh/str-vs-repr-in-python-and-when-to-use-them-58e5</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;In a previous post, we have done a comparison between &lt;code&gt;__new__&lt;/code&gt; and &lt;code&gt;__init__&lt;/code&gt;. In this post, we are going to do something similar, but with a different pair.&lt;/p&gt;

&lt;p&gt;For those who don't know, &lt;code&gt;__str__()&lt;/code&gt; and &lt;code&gt;__repr__()&lt;/code&gt; are two dunder methods which you can override in a class to change the way class is represented.&lt;/p&gt;

&lt;p&gt;These two little functions have been a source of confusion in my early career. Let us first go through them one by one and let us understand what they do first. Then we'll do comparison among them with respect to their similarities and differences.&lt;/p&gt;

&lt;h2&gt;
  
  
  __str__() and str()
&lt;/h2&gt;

&lt;p&gt;If you have worked with other language before coming to Python, you might be familiar with &lt;code&gt;str()&lt;/code&gt; or &lt;code&gt;string()&lt;/code&gt; function, which would cast any other data type to String data type or class.&lt;/p&gt;

&lt;p&gt;Python behaves the same. Here is an example in Python REPL.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;my_int&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;type&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;my_int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="nc"&gt;int&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="gp"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;my_str&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;my_int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;type&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;my_str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="nc"&gt;str&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Simlar is the &lt;code&gt;repr()&lt;/code&gt; function. &lt;code&gt;repr&lt;/code&gt; also returns a string.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;my_int&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;type&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;my_int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="nc"&gt;int&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="gp"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;my_repr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;repr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;my_int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;type&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;my_repr&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="nc"&gt;str&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  __repr__() and repr()
&lt;/h2&gt;

&lt;p&gt;By now you understand that both the dunder method has their corresponding function symbols in which you can pass another data type.&lt;br&gt;
 We also saw in the previous section that when you pass anything to repr(), it simply turns into a str data type.&lt;/p&gt;
&lt;h2&gt;
  
  
  __str__() and __repr__() in a Class
&lt;/h2&gt;

&lt;p&gt;If you still don't know about dunder methods, this section might help you undestand it.&lt;/p&gt;

&lt;p&gt;There is a &lt;a href="https://www.reddit.com/r/Python/comments/br9ok2/list_of_all_python_dunder_methods/" rel="noopener noreferrer"&gt;massive list of Python dunder methods&lt;/a&gt;. Dunder methods allow the way your handwritten class to behave in a certain manner.&lt;/p&gt;

&lt;p&gt;The difference between the two methods is that &lt;code&gt;__str__&lt;/code&gt; is intended to provide a human-readable representation of the object, while &lt;code&gt;__repr__&lt;/code&gt; should provide a representation that can be used to recreate the object.&lt;/p&gt;

&lt;p&gt;Let's see the difference between the two with the help of a simple code example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Point&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__str__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;(&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;, &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;)&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__repr__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Point(&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;, &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;)&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

&lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Point&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&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="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# Output: (1, 2)
&lt;/span&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;repr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="c1"&gt;# Output: Point(1, 2)
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the example above, &lt;code&gt;__str__&lt;/code&gt; returns a string representation of the Point object that is intended to be human-readable. The &lt;code&gt;__repr__&lt;/code&gt; method returns a string representation that could be used to recreate the object.&lt;/p&gt;

&lt;p&gt;In general, it is recommended to always define a &lt;code&gt;__repr__&lt;/code&gt; method for your objects, so that you have an unambiguous representation of the object that can be used for debugging or in a REPL environment. On the other hand, &lt;code&gt;__str__&lt;/code&gt; is typically only defined when a more human-readable representation is needed. If &lt;code&gt;__str__&lt;/code&gt; is not defined for an object, &lt;code&gt;repr(obj)&lt;/code&gt; is used as a fallback.&lt;/p&gt;

&lt;p&gt;It's worth noting that the &lt;code&gt;__str__&lt;/code&gt; method should return a string, while the &lt;code&gt;__repr__&lt;/code&gt; method should return a string that, when passed to the &lt;code&gt;eval()&lt;/code&gt; function, returns an object with the same value. The recommended format for &lt;code&gt;__repr__&lt;/code&gt; is a string that, when passed to &lt;code&gt;eval()&lt;/code&gt;, creates an object with the same value as the original. In the example above, the &lt;code&gt;Point&lt;/code&gt; object can be recreated by calling &lt;code&gt;Point(1, 2)&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;In conclusion, &lt;code&gt;__str__&lt;/code&gt; and &lt;code&gt;__repr__&lt;/code&gt; are two important methods in Python that allow you to define string representations of objects. Understanding the difference between the two and when to use them is important in creating robust and well-designed code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Keep reading&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.geeksforgeeks.org/str-vs-repr-in-python/" rel="noopener noreferrer"&gt;https://www.geeksforgeeks.org/str-vs-repr-in-python/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>announcement</category>
      <category>discuss</category>
      <category>ai</category>
      <category>productivity</category>
    </item>
    <item>
      <title>How to Control Philips Wiz Bulb Using Go</title>
      <dc:creator>Santosh Kumar</dc:creator>
      <pubDate>Fri, 17 Feb 2023 18:30:00 +0000</pubDate>
      <link>https://forem.com/santosh/how-to-control-philips-wiz-bulb-using-go-2ad9</link>
      <guid>https://forem.com/santosh/how-to-control-philips-wiz-bulb-using-go-2ad9</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;I have always been conscious about privacy and it was the sole reason I wasn't early adapter of smart home devices. This changed when I bought Raspberry Pi. I learned that I can make my Pi hub to all the smart devices at my home.&lt;/p&gt;

&lt;p&gt;And this is how I bought 9W Philips Wiz light; the cheapest one I could get in the Indian market.&lt;/p&gt;

&lt;p&gt;To use this product, you at least need to have a home network (a wifi router will work). The router does not need to have internet connection.&lt;/p&gt;

&lt;h2&gt;
  
  
  Control Philips Wiz using App
&lt;/h2&gt;

&lt;p&gt;The most common way to control the Wiz light is using the mobile app. It is available for both &lt;a href="https://play.google.com/store/apps/details?id=com.tao.wiz&amp;amp;hl=en_IN&amp;amp;gl=US&amp;amp;pli=1" rel="noopener noreferrer"&gt;Android&lt;/a&gt; and &lt;a href="https://apps.apple.com/us/app/wiz-connected/id1497247770" rel="noopener noreferrer"&gt;iOS&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I don't want to cover how to operate the bulb using the app. I would leave it upto you. I want you to explore the app completely before proceeding towards the next section.&lt;/p&gt;

&lt;p&gt;As we are going to control the bulb using code, I want you to practice doing these actions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Turn on/off&lt;/li&gt;
&lt;li&gt;Set colors&lt;/li&gt;
&lt;li&gt;Set brightness&lt;/li&gt;
&lt;li&gt;Set temperature&lt;/li&gt;
&lt;li&gt;Set modes&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Control Philips Wiz using Go
&lt;/h2&gt;

&lt;p&gt;While there are libraries available to interact with the bulb, I wanted to show you guys what happens internally with the bulb. In a home automation scenario, you'd mostly be using such libraries.&lt;/p&gt;

&lt;h3&gt;
  
  
  Find the bulb IP
&lt;/h3&gt;

&lt;p&gt;Before we write any piece of code, it is crucial to find out the IP of your bulb. In most latest routers, they show what clients are connected to the router, the device name should appear as &lt;code&gt;wiz_xxxxxx&lt;/code&gt; where &lt;code&gt;xxxxxx&lt;/code&gt; is the starting mac address of the bulb.&lt;/p&gt;

&lt;p&gt;If somehow your router does not supports showing the IP of connected devices, you'll have to do some hit and trial.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Get the IP of your PC/Laptop. You can run &lt;code&gt;ip a&lt;/code&gt; if you are on Linux. My PC's IP is &lt;code&gt;192.168.0.100&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Turn off the light from the app and send the &lt;em&gt;Hello Philips Wiz&lt;/em&gt; code described in next section to each of the IPs near to your PCs IP. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So I'd send following message to 192.168.0.95-105. How many machines you have to try depends on how many devices you have on your network.&lt;/p&gt;

&lt;p&gt;We need the IP because we are going to communicate with bulb by sending and receiving UDP messages.&lt;/p&gt;

&lt;h3&gt;
  
  
  Hello Philips Wiz using UDP
&lt;/h3&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;main&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="s"&gt;"net"&lt;/span&gt;

&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;wizIP&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"192.168.0.101"&lt;/span&gt;  &lt;span class="c"&gt;// this is address on my bulb in my network&lt;/span&gt;
&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;wizPort&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"38899"&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&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;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;net&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Dial&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"udp"&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;Sprintf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"%s:%s"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;wizIp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;wizPort&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="nb"&gt;panic&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"could not connect to wiz light"&lt;/span&gt;&lt;span class="p"&gt;)&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;Write&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="s"&gt;`{"method": "setPilot", "params":{"state": true}}`&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;Starting at line 5, first we have to define the IP of the bulb. It is &lt;code&gt;192.168.0.101&lt;/code&gt; in my case.&lt;/p&gt;

&lt;p&gt;Next we have to define the port on which Wiz light listens on. This port ID is constant and won't change unlike the &lt;code&gt;wizIP&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Line 14 is the most important. The message is actually a JSON. Let's beautify it before discussing about it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"method"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"setPilot"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"params"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"state"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;"method": The first key in the JSON object is &lt;code&gt;method&lt;/code&gt;. This is either &lt;code&gt;getPilot&lt;/code&gt; or &lt;code&gt;setPilot&lt;/code&gt; depending on whether you want to get the state of the bulb, or set a state to the bulb. In our case, we are going to set some state. I have never really used the &lt;code&gt;getPilot&lt;/code&gt; method, yet.&lt;/li&gt;
&lt;li&gt;"params": Next in the JSON object is parameters we are sending; it is denoted by &lt;code&gt;params&lt;/code&gt; in the JSON body. This is going to complement the &lt;code&gt;method&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Now depending on what we are trying to do with the bulb, the params are going to change. In above code, we are just saying to set the &lt;code&gt;state&lt;/code&gt; to &lt;code&gt;true&lt;/code&gt;, which literally means to start the bulb.&lt;/p&gt;

&lt;p&gt;If your bulb was off, it would have turned on after running the above code.&lt;/p&gt;

&lt;p&gt;Similarly, if you want to turn it off, change the state to &lt;code&gt;false&lt;/code&gt; and send the message again.&lt;/p&gt;

&lt;h3&gt;
  
  
  Set custom colors
&lt;/h3&gt;

&lt;p&gt;Wiz accepts RGB colors values. If you don't know what that means, go to google and type in "rgb color picker", then choose a color and then note the RGB value. For example, value for pure &lt;strong&gt;red&lt;/strong&gt; would be 255, 0, 0. Here 255 is the value of red, and 0 is for both green and blue.&lt;/p&gt;

&lt;p&gt;To set Wiz to red color, this message can be sent:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"method"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"setPilot"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"params"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"r"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"g"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"b"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You have already seen how to send that message.&lt;/p&gt;

&lt;h3&gt;
  
  
  Set brightness
&lt;/h3&gt;

&lt;p&gt;In the app UI, you must have seen the brightness slider? If not, consider the following screenshot.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fd2kbulfv42d43j.cloudfront.net%2F2023%2FQ1%2Fphilips-wiz-app-controls.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fd2kbulfv42d43j.cloudfront.net%2F2023%2FQ1%2Fphilips-wiz-app-controls.jpg" alt="App showing temperature and brightness slider" width="800" height="457"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;First of all, I have warm white light selected. The top slider is for temperature, which we are going to talk about in next section.&lt;/p&gt;

&lt;p&gt;The lowest value for brightness is 10, and max is 100. You guessed it right, lowest is not 0 because at 0, the bulb will be off.&lt;/p&gt;

&lt;p&gt;You can club brightness setting with scene settings as well as any color setting. In following message, I'm setting the color to green and brightness to 50%.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"method"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"setPilot"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"params"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"r"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"g"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"b"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"dimming"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Set temperature
&lt;/h3&gt;

&lt;p&gt;Setting temperature is similarly easy. There is a params called &lt;code&gt;temp&lt;/code&gt;. The range is between 2200 to 6200.&lt;/p&gt;

&lt;p&gt;To the best of my knowledge, temperature can only be clubbed with brightness.&lt;/p&gt;

&lt;p&gt;Here I'm presenting you an example payload for the message demonstrating 2200 kelvin temperate with a intensity of 20%.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"method"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"setPilot"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"params"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"temp"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2200&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"dimming"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;When I bought my Philips Wiz, I had no intention of controlling it programatically. It would such an overkill.&lt;/p&gt;

&lt;p&gt;But shortly after this buy, I also &lt;a href="https://dev.to/posts/2023/first-month-with-my-raspberry-pi/"&gt;bought a Raspberry Pi&lt;/a&gt;. I became aware that this programatic access can be integrated by home automation.&lt;/p&gt;

&lt;p&gt;Libraries already exist in Python. One of them is &lt;a href="https://github.com/sbidy/pywizlight" rel="noopener noreferrer"&gt;pywizlight&lt;/a&gt;, which seems to be most mature. But there are many more.&lt;/p&gt;

&lt;p&gt;Maybe we could write some similar library in Go. &lt;/p&gt;

</description>
      <category>welcome</category>
    </item>
    <item>
      <title>First Month With My Raspberry Pi</title>
      <dc:creator>Santosh Kumar</dc:creator>
      <pubDate>Fri, 17 Feb 2023 10:59:00 +0000</pubDate>
      <link>https://forem.com/santosh/first-month-with-my-raspberry-pi-4003</link>
      <guid>https://forem.com/santosh/first-month-with-my-raspberry-pi-4003</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;It's no longer than a month since I bought a Raspberry Pi. Pi 4B to be precise. In this post, I'm going to log how I spent my 1st month with it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setup the Pi
&lt;/h2&gt;

&lt;p&gt;When I decided to buy Raspi, I decided not to go with the kit. The reason was the model I was looking for, which is &lt;em&gt;8GB Model B&lt;/em&gt; wasn't available in India. And finding a kit for it would have been more challenging.&lt;/p&gt;

&lt;p&gt;So I bought the Pi itself from &lt;a href="https://www.olelectronics.in/product/raspberry-pi-4-8gb-model-b/" rel="noopener noreferrer"&gt;&lt;strong&gt;OL Electronics&lt;/strong&gt;&lt;/a&gt;. It cost me &lt;strong&gt;₹10,700&lt;/strong&gt; INR with taxes and delivery charge.&lt;/p&gt;

&lt;p&gt;As you might know, Pi does not ship with a power adapter. So I bought one from &lt;a href="https://robu.in/product/orange-power-supply-adapter-charger-5v-3a-c-type/" rel="noopener noreferrer"&gt;robu.in&lt;/a&gt;. It cost me &lt;strong&gt;₹315&lt;/strong&gt; with delivery charges.&lt;/p&gt;

&lt;p&gt;Pi also does not comes with a memory card. I tried searching for 64 micro sd cards offline and online. The best deal was from Amazon. It cost me &lt;strong&gt;₹539&lt;/strong&gt;. You will also need a card reader, which I bought from the local market at a price of &lt;strong&gt;₹30&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;While flashing, I choose to use the Lite variant of OS which comes without a desktop environment and has a footprint of 300 MB on disk.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting up the OS
&lt;/h2&gt;

&lt;p&gt;The Pi board, a 5V 3A Type-C power adapter, a micro sd, and a card reader is all you need to boot up a Pi. You don't need a monitor or HDMI adapter if you already have a laptop because you can also SSH to your Pi to do your work remotely and that is how I usually work on my Pi.&lt;/p&gt;

&lt;p&gt;As you know, I use Ubuntu on my machine. If you are also using Ubuntu, you can install it by:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo apt install rpi-imager
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Instruction for other operating systems can be found on &lt;a href="https://github.com/raspberrypi/rpi-imager" rel="noopener noreferrer"&gt;their GitHub page&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Put a micro sd card in the card reader and Please consider watching &lt;a href="https://www.youtube.com/watch?v=ntaXWS8Lk34" rel="noopener noreferrer"&gt;How to use Raspberry Pi Imager&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Blink Light
&lt;/h2&gt;

&lt;p&gt;I prefer to use the gpiozero package for dealing with GPIO. But there is also an &lt;code&gt;RPi&lt;/code&gt; module.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;gpiozero&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;LED&lt;/span&gt;

&lt;span class="n"&gt;led&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;LED&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;18&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;led&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;led&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;off&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Make sure you attach the long head of the LED to pin 18.&lt;/p&gt;

&lt;p&gt;There is also an equivalent code using the &lt;code&gt;RPi&lt;/code&gt; package:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;RPi.GPIO&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;GPIO&lt;/span&gt;

&lt;span class="n"&gt;led_pin&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;18&lt;/span&gt;
&lt;span class="n"&gt;GPIO&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setmode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;GPIO&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;BCM&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;GPIO&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;led_pin&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;GPIO&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;OUT&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;GPIO&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;output&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;led_pin&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;GPIO&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;output&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;led_pin&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I have also short a video I have &lt;a href="https://instagram.com/fullstackwithsantosh" rel="noopener noreferrer"&gt;posted on Instagram&lt;/a&gt;. Here it is:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fd2kbulfv42d43j.cloudfront.net%2F2023%2FQ1%2Fraspi-blink-led.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fd2kbulfv42d43j.cloudfront.net%2F2023%2FQ1%2Fraspi-blink-led.gif" alt="Blinking LED using GPIO programming" width="360" height="640"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Actuate on Proximity
&lt;/h2&gt;

&lt;p&gt;Here I have used both packages to run something when the proximity sensor detects any object near the sensor.&lt;/p&gt;

&lt;p&gt;The sensor I am using is an IR proximity sensor.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;

&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;gpiozero&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;LED&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;RPi.GPIO&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;GPIO&lt;/span&gt;

&lt;span class="n"&gt;GPIO&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setmode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;GPIO&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;BOARD&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;GPIO&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;GPIO&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IN&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;led&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;LED&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;18&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="bp"&gt;True&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;GPIO&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;input&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;turning light on&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;led&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;else&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;turning light off&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;led&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;off&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;0.1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fd2kbulfv42d43j.cloudfront.net%2F2023%2FQ1%2Fraspi-actuate-on-proximity.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fd2kbulfv42d43j.cloudfront.net%2F2023%2FQ1%2Fraspi-actuate-on-proximity.gif" alt="IR sensor in action" width="360" height="640"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Controlling LED brightness, 0-100 and back
&lt;/h2&gt;

&lt;p&gt;Below is Python code to change the brightness of a LED light using Raspberry Pi.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;RPi.GPIO&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;GPIO&lt;/span&gt;

&lt;span class="n"&gt;led_pin&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;18&lt;/span&gt;
&lt;span class="n"&gt;GPIO&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setmode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;GPIO&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;BCM&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;GPIO&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;led_pin&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;GPIO&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;OUT&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;pwm_led&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;GPIO&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;PWM&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;led_pin&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;pwm_led&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;start&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;start&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="n"&gt;end&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;
    &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="n"&gt;start&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;end&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;pwm_led&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;ChangeDutyCycle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(.&lt;/span&gt;&lt;span class="mi"&gt;025&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;start&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
    &lt;span class="k"&gt;break&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I don't shoot a video for this one because the intensity was so low that it was very hard to distinguish between different strengths of light.&lt;/p&gt;

&lt;h2&gt;
  
  
  Controlling an RGB light (failed)
&lt;/h2&gt;

&lt;p&gt;I have also bought a common cathode LED. But somehow, I'm not able to turn on the LED. Not sure if the problem is in the LED, my code, or the pins.&lt;/p&gt;

&lt;p&gt;Here is the code I was using.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;gpiozero&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;RGBLED&lt;/span&gt;

&lt;span class="n"&gt;led&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;RGBLED&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;22&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;27&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;17&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;led&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;color&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And here is the setup I was using.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fd2kbulfv42d43j.cloudfront.net%2F2023%2FQ1%2Fraspi-rgb-led-failed.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fd2kbulfv42d43j.cloudfront.net%2F2023%2FQ1%2Fraspi-rgb-led-failed.jpg" alt="Failed attempt to use RGB LED" width="800" height="600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the above image, the blue, green, and red are placed at 6, 7, and 8 on the left column, and the common cathode is placed at 3rd from the right.&lt;/p&gt;

&lt;p&gt;Please let me know if you have a solution for this one.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;This is not the entirety of the things I have done with my Raspberry Pi in the first month. I have a DHT11 sensor which I mistakenly bought without the IC. And now I need a 4.7K resistor to work with it. I am yet to order the resistor.&lt;/p&gt;

&lt;p&gt;Alongside Raspi accessories, I have also bought some NFC tags to play with. I will post another blog if I make something interesting with it.&lt;/p&gt;

&lt;p&gt;Installing Home Assistant is another thing that I have done on my Pi. This board is going to be the hub of other smart devices on my network. I'm planning to buy some ESF32 to help me with my home automation journey.&lt;/p&gt;

&lt;p&gt;If you are also keen on home automation and IoT, I'd recommend you &lt;a href="https://github.com/microsoft/IoT-For-Beginners" rel="noopener noreferrer"&gt;IoT for Beginners&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Let me know if you want more articles like this one.&lt;/p&gt;

</description>
      <category>coding</category>
      <category>discuss</category>
    </item>
    <item>
      <title>How to Write Classes in Golang</title>
      <dc:creator>Santosh Kumar</dc:creator>
      <pubDate>Thu, 16 Feb 2023 15:01:00 +0000</pubDate>
      <link>https://forem.com/santosh/how-to-write-classes-in-golang-52dn</link>
      <guid>https://forem.com/santosh/how-to-write-classes-in-golang-52dn</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;I have seen many people coming from Python background struggling with Go. What I have obeserved it they write code that is limited to writing functions and calling them. They never leverage design constructs such as abstraction, encapsulation, inheritance, composition etc. I can understand their pain because I've been in the same boat.&lt;/p&gt;

&lt;p&gt;In today's post I'll compare how we write classes in Python vs how we do the same thing in a Go way.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is a class composed of?
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Attributes in form of variables&lt;/li&gt;
&lt;li&gt;Behavior in form of methods&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Example in Python
&lt;/h2&gt;

&lt;p&gt;Consider the following code in Python that defines a simple Person class with a name attribute and a greet method:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Person&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="bp"&gt;self&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;name&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;greet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s"&gt;"Hello, my name is &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Person&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"John"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;greet&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;  &lt;span class="c1"&gt;# prints "Hello, my name is John"
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you're a Python programmer looking to learn Go, you'll be happy to know that Go has a similar concept to classes called "structs". Structs are similar to classes in that they allow you to define a custom data type with its own fields and methods.&lt;/p&gt;

&lt;h2&gt;
  
  
  Struct to define the structure and attributes
&lt;/h2&gt;

&lt;p&gt;To define a struct in Go, you use the type keyword followed by the name of the struct and a set of curly braces containing the fields. Here's an example of a simple struct called Person:&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;Person&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="n"&gt;age&lt;/span&gt;  &lt;span class="kt"&gt;int&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This defines a struct called Person with two fields: name and age, both of which are of type string and int respectively.&lt;/p&gt;

&lt;h2&gt;
  
  
  Method or behaviour using receiver function
&lt;/h2&gt;

&lt;p&gt;You can also define methods on your structs by using the func keyword and attaching the method to the struct using the (p *Person) syntax, where p is the receiver of the method and Person is the type of the receiver. Here's an example of a method called SayHello that prints a greeting to the console:&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="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;Person&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;SayHello&lt;/span&gt;&lt;span class="p"&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;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Hello, my name is %s and I am %d years old&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;p&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;p&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;age&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;To create an instance of a struct, you can use the new function or the shorthand syntax :=. Here's an example of both:&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="c"&gt;// Using the new function&lt;/span&gt;
&lt;span class="n"&gt;p1&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;Person&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;p1&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"John"&lt;/span&gt;
&lt;span class="n"&gt;p1&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;age&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="m"&gt;30&lt;/span&gt;

&lt;span class="c"&gt;// Using the shorthand syntax&lt;/span&gt;
&lt;span class="n"&gt;p2&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;Person&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="s"&gt;"Jane"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;age&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="m"&gt;25&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can also define a "constructor" function to create instances of your struct. This can be useful if you want to perform some initialization logic when creating a new instance. Here's an example of a constructor function for the Person 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;NewPerson&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="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;age&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;Person&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;p&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;Person&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="o"&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;name&lt;/span&gt;
    &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;age&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;age&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can then use this constructor function to create a new instance of the Person struct like this:&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;p&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;NewPerson&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Bob"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;35&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I hope this tutorial has helped you understand how to define and use structs in Go as a Python programmer. Structs are a powerful and flexible way to define custom data types in Go, and I encourage you to explore them further.&lt;/p&gt;

&lt;p&gt;Thank you for reading!&lt;/p&gt;

</description>
      <category>go</category>
      <category>python</category>
      <category>oops</category>
    </item>
    <item>
      <title>Testing HTTP Requests with Postman</title>
      <dc:creator>Santosh Kumar</dc:creator>
      <pubDate>Wed, 15 Feb 2023 06:20:00 +0000</pubDate>
      <link>https://forem.com/santosh/testing-http-requests-with-postman-534i</link>
      <guid>https://forem.com/santosh/testing-http-requests-with-postman-534i</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;In &lt;a href="https://dev.to/posts/2022/postman-premier-the-minimal-postman-you-need-to-learn/"&gt;Postman Premier - The Minimal Postman you need to Learn&lt;/a&gt;, I posted the minimum of Postman you need to learn. In this article, I'm going to expand on that knowledge and dig more into the response. In this post, I'll be asserting the response on certain values and response codes and more. &lt;/p&gt;

&lt;h2&gt;
  
  
  What are assertions and how to use it
&lt;/h2&gt;

&lt;p&gt;Assertions are nothing but test cases we give to a particular request. In the previous post, we already have seen that each of the requests has a &lt;strong&gt;Tests&lt;/strong&gt; tab. There we write code in JavaScript, judging specific parameters of the response.&lt;/p&gt;

&lt;p&gt;Let's first test for a specific status code. Just for context, while testing, I'm going to use my gingo server.&lt;/p&gt;

&lt;h2&gt;
  
  
  Looking for a specific status code
&lt;/h2&gt;

&lt;p&gt;Testing for a specific status code is one of the easiest tasks to do within Postman. I'm going to use my &lt;code&gt;GET {{baseUrl}}/books&lt;/code&gt; endpoint for this purpose.&lt;/p&gt;

&lt;p&gt;When you open the &lt;strong&gt;Tests&lt;/strong&gt; tab, you'll see snippets on the right side column. Click on &lt;strong&gt;Status code: Code is 200&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The code area will be populated with the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;pm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Status code is 200&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;pm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;have&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;200&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 you send the request, you'll see &lt;strong&gt;Test Results (1/1)&lt;/strong&gt; under the response section. That area shows how many of your tests have passed or failed.&lt;/p&gt;

&lt;p&gt;I've recorded a gif for you.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--EzbnotcP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://d2kbulfv42d43j.cloudfront.net/2022/Q4/postman-looking-for-specific-status-code.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--EzbnotcP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://d2kbulfv42d43j.cloudfront.net/2022/Q4/postman-looking-for-specific-status-code.gif" alt="Testing for specific status code" width="817" height="534"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This was for the positive assertions, you can send wrong data and do a negative assertion as well.&lt;/p&gt;

&lt;h2&gt;
  
  
  Looking for a specific string in the body
&lt;/h2&gt;

&lt;p&gt;For this test, I'll be using the &lt;code&gt;GET {{baseUrl}}/books/:isbn&lt;/code&gt; endpoint, with &lt;code&gt;isbn&lt;/code&gt;'s value to be &lt;code&gt;9781612680194&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Looking for a specific string in the body is not much different from checking for a status code. You'll find a snippet for it as well. Snippets are a great way to explore assertion in Postman.&lt;/p&gt;

&lt;p&gt;Look for an assertion called &lt;strong&gt;Response body: Contains string&lt;/strong&gt;. It will spit this source code into the test panel.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;pm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Body matches string&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;pm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;pm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;()).&lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;include&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;string_you_want_to_search&lt;/span&gt;&lt;span class="dl"&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;I'm going to modify the body:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;pm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Body includes Rich Dad Poor Dad&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;pm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;pm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;()).&lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;include&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Rich Dad Poor Dad&lt;/span&gt;&lt;span class="dl"&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 I'm not going to include a gif for this as this would be very identical to the previous one.&lt;/p&gt;

&lt;h2&gt;
  
  
  Looking for a specific header
&lt;/h2&gt;

&lt;p&gt;Another thing we can test in a REST API is headers. Some use cases to look for a header are:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;When you are expecting a specific content type&lt;/li&gt;
&lt;li&gt;When you are expecting an authentication token as a response to a request.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;For a header, the testing code would look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;pm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Content-Type is application/json&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;pm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;have&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;header&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;application/json&lt;/span&gt;&lt;span class="dl"&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;h2&gt;
  
  
  Adding tests at the collection level
&lt;/h2&gt;

&lt;p&gt;Response time is another thing to test if your API is time critical. This time we don't add this test on a request basis. We are programmers and we DRY. Checking for responses is going to be for each and every request, it's better to add it at the collection level.&lt;/p&gt;

&lt;p&gt;To add a test at the collection level, click on the collection name on the left panel. As already discussed, you'd see &lt;strong&gt;Authorization&lt;/strong&gt;, &lt;strong&gt;Pre-request Script&lt;/strong&gt;, &lt;strong&gt;Tests&lt;/strong&gt; and &lt;strong&gt;Variables&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Navigate to &lt;strong&gt;Tests&lt;/strong&gt;, and put this in the code area:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;pm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Response time is less than 500ms&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;pm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;pm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;responseTime&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;be&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;below&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;500&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;500ms is good enough for local testing. If your server is over the internet, you might need to modify it to suit your need.&lt;/p&gt;

&lt;p&gt;This test will run for every request which is there in the collection and for each new request, you add to the collection.&lt;/p&gt;

&lt;h2&gt;
  
  
  Run all tests from a collection
&lt;/h2&gt;

&lt;p&gt;When you click on a collection, you'll see a Run button at the top right corner. When you click that, you'll be asked which tests you want to run.&lt;/p&gt;

&lt;p&gt;This is the Collection Runner UI. When you are done with all the config. Click on the &lt;strong&gt;Run Postman Premier&lt;/strong&gt; to run all the tests and see the results.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;We have learned enough Postman to get our wheels rolling. There's much more to Postman than we have discussed in 2 articles on Fullstack with Santosh. Lots of features keep getting added in each release. You can keep yourself updated by following &lt;a href="https://learning.postman.com/docs/getting-started/introduction/"&gt;Postman Docs&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>postman</category>
      <category>testing</category>
      <category>apitesting</category>
      <category>api</category>
    </item>
    <item>
      <title>Postman Premier - The Minimal Postman you need to Learn</title>
      <dc:creator>Santosh Kumar</dc:creator>
      <pubDate>Mon, 13 Feb 2023 15:32:27 +0000</pubDate>
      <link>https://forem.com/santosh/postman-premier-the-minimal-postman-you-need-to-learn-k4m</link>
      <guid>https://forem.com/santosh/postman-premier-the-minimal-postman-you-need-to-learn-k4m</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Welcome to my Fullstack with Santosh. Today we are going to learn about how to use Postman as a backend engineer to make our daily life easier. Postman is an API testing tool where you can test your REST APIs. It has now developed into handling many different kinds of interfaces, but today we are going to focus on the REST APIs.&lt;/p&gt;

&lt;p&gt;Make sure you have Postman already installed. I work on Ubuntu and the way I install is &lt;code&gt;sudo snap install postman&lt;/code&gt;. You can find instructions about your platform on the downloads page: &lt;a href="https://www.postman.com/downloads/" rel="noopener noreferrer"&gt;https://www.postman.com/downloads/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When you open Postman for the first time, you might see a screen similar to this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fd2kbulfv42d43j.cloudfront.net%2F2022%2FQ4%2Fpostman-home-screen.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fd2kbulfv42d43j.cloudfront.net%2F2022%2FQ4%2Fpostman-home-screen.png" alt="Postman home screen" width="800" height="567"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Your home screen might appear a little different because 1. I have already signed in. 2. I have already created some workspaces. 3. I have changed the theme to dark.&lt;/p&gt;

&lt;h2&gt;
  
  
  Create a collection
&lt;/h2&gt;

&lt;p&gt;Before you even start to test endpoints in your server, the first thing you'd do is create a collection. Press that little &lt;strong&gt;+&lt;/strong&gt; button on the left column.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fd2kbulfv42d43j.cloudfront.net%2F2022%2FQ4%2Fpostman-create-new-collection.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fd2kbulfv42d43j.cloudfront.net%2F2022%2FQ4%2Fpostman-create-new-collection.png" alt="Create new collection" width="315" height="237"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Give it a name. I'm going to name it &lt;strong&gt;Postman Premier&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;There are a lot more things that can be done with a Collection. But for now, let's not get deep into it.&lt;/p&gt;

&lt;p&gt;Note: If you don't have an API to test, you can refer to my previous blog posts: &lt;a href="https://dev.to/posts/2022/building-a-bookstore-api-in-golang-with-gin/"&gt;Building a Book Store API in Golang With Gin&lt;/a&gt; and &lt;a href="https://dev.to/posts/2022/how-to-integrate-swagger-ui-in-go-backend-gin-edition/"&gt;How to Integrate Swagger UI in Go Backend - Gin Edition&lt;/a&gt; where I show how you can develop your simple CRUD server in Go. It's worth a look.&lt;/p&gt;

&lt;h2&gt;
  
  
  Working with Requests
&lt;/h2&gt;

&lt;p&gt;I am going to test my gingo server, which is a CRUD server I have developed before. I already have linked them above.&lt;/p&gt;

&lt;h3&gt;
  
  
  Creating a GET Request to get introduced to UI
&lt;/h3&gt;

&lt;p&gt;I have already run my gingo server and I am going to make a GET request at &lt;code&gt;http://localhost:8090/api/v1/books&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Creating a request is straightforward in Postman. Let's start with creating a GET request.&lt;/p&gt;

&lt;p&gt;When you expand your created collection on the left column, you'll see a link called &lt;strong&gt;Create a request&lt;/strong&gt;. Click on that, and a tab will open in the main column.&lt;/p&gt;

&lt;p&gt;In that window, a text will already be selected. This is the identifier of the request. I like to name my request the same as the path of the endpoint. In my case, I'm going to name it &lt;code&gt;/books&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The next thing you do is select a &lt;strong&gt;verb&lt;/strong&gt;. There is a dropdown just below the name of the request. This will by default be &lt;code&gt;GET&lt;/code&gt;. For this particular request, we don't modify that.&lt;/p&gt;

&lt;p&gt;Next, we'll input the address of the endpoint we need to hit. I've input &lt;code&gt;http://localhost:8090/api/v1/books&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;We don't need any other setting for now. Don't be intimidated by the UI if you don't understand it yet.&lt;/p&gt;

&lt;p&gt;I have recorded a gif for your reference. Here it goes. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fd2kbulfv42d43j.cloudfront.net%2F2022%2FQ4%2Fpostman-create-a-get-request.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fd2kbulfv42d43j.cloudfront.net%2F2022%2FQ4%2Fpostman-create-a-get-request.gif" alt="Create a GET request" width="1047" height="565"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;What we covered in this section: Creating a request, request name, request verb, and request path.&lt;/p&gt;

&lt;h3&gt;
  
  
  Path Parameters
&lt;/h3&gt;

&lt;p&gt;We can get all books. Let us get a specific book; by ISBN.&lt;/p&gt;

&lt;p&gt;The quickest way to create our next request is to duplicate the previous one and modify the duplicated one.&lt;/p&gt;

&lt;p&gt;Let us name this new request &lt;code&gt;/books/:isbn&lt;/code&gt;. For the path, we're going to use &lt;code&gt;localhost:8090/api/v1/books/:isbn&lt;/code&gt;. As soon as you write &lt;code&gt;:isbn&lt;/code&gt; in the path input, &lt;strong&gt;Params&lt;/strong&gt; section will be highlighted.&lt;/p&gt;

&lt;p&gt;When you navigate to that tab, you'd see &lt;code&gt;isbn&lt;/code&gt; is already added as KEY in &lt;strong&gt;Path Variables&lt;/strong&gt; section. You need to provide value. You can get ISBN from the response of the previous endpoint we tested. E.g. &lt;code&gt;9781612680194&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;When you do this much, you should see a single book in the response, unlike the previous response, which had all the books.&lt;/p&gt;

&lt;p&gt;Below is a gif for this section.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fd2kbulfv42d43j.cloudfront.net%2F2022%2FQ4%2Fpostman-working-with-path-params.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fd2kbulfv42d43j.cloudfront.net%2F2022%2FQ4%2Fpostman-working-with-path-params.gif" alt="Working with path params" width="933" height="473"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Creating a POST Request and working with Body and Headers
&lt;/h3&gt;

&lt;p&gt;Duplicate the first endpoint we created again, but this time, change the verb to &lt;code&gt;POST&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;In the previous section &lt;strong&gt;Params&lt;/strong&gt; section was highlighted. This time you need to highlight the &lt;strong&gt;Body&lt;/strong&gt; section.&lt;/p&gt;

&lt;p&gt;When you highlight &lt;strong&gt;Body&lt;/strong&gt;, you'll see a group of radio buttons. Click on the one labeled with &lt;strong&gt;raw&lt;/strong&gt;. A dropdown will appear at the right with the text &lt;strong&gt;Text&lt;/strong&gt;. Click on the dropdown and select &lt;strong&gt;JSON&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;When you select JSON from the dropdown, a new header is added to the request. You can see the header when you highlight the &lt;strong&gt;Headers&lt;/strong&gt; tab. In this tab, you can see many other headers already added by Postman.&lt;/p&gt;

&lt;p&gt;When the header is set, use the following body to make a POST request:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"isbn"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"9780137081073"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"The Clean Coder"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"author"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Robert C. Martin"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here is a gif of me doing the same thing.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fd2kbulfv42d43j.cloudfront.net%2F2022%2FQ4%2Fpostman-working-with-body-and-header.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fd2kbulfv42d43j.cloudfront.net%2F2022%2FQ4%2Fpostman-working-with-body-and-header.gif" alt="Working with body and header" width="933" height="473"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For those who don't know. Headers are not limited to POST requests. It might be required for a GET endpoint to have an auth token in its header.&lt;/p&gt;

&lt;p&gt;Making requests for other verbs such as DELETE and PUT is no different. I left it over for you to try with those.&lt;/p&gt;

&lt;h2&gt;
  
  
  Working with variables
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Using Collection variables
&lt;/h3&gt;

&lt;p&gt;We have different variable scopes available when working with Postman:&lt;/p&gt;

&lt;p&gt;Global &amp;gt; Collection &amp;gt; Environment &amp;gt; Local&lt;/p&gt;

&lt;p&gt;They all have their use case:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Global&lt;/strong&gt; - Global variables are global to all the collections you have in Postman. This should be mostly avoided.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Collection&lt;/strong&gt; - This one is my favorite. You can have collection-level variables for say credentials, baseurl, etc.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Environment&lt;/strong&gt; - If you are testing a collection with multiple data sets or conditions. Environment variables come to use.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Local&lt;/strong&gt; - Local variables are local to request and will override all other scopes variables. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I'll demonstrate &lt;strong&gt;Collection&lt;/strong&gt; variables, but all behave the same way and have similar UI.&lt;/p&gt;

&lt;p&gt;Click on the Postman Premier collection and you'll see 4 tabs. &lt;em&gt;Authorization&lt;/em&gt;, &lt;em&gt;Pre-request Script&lt;/em&gt;, &lt;em&gt;Tests&lt;/em&gt; and &lt;em&gt;Variables&lt;/em&gt;. Click on the variables.&lt;/p&gt;

&lt;p&gt;Collection Variables use case: We are doing a lot of repetitions in each of the requests. We are inputting the base URL of the server each time. If we had to somehow modify the port address, we would have to modify it for all.&lt;/p&gt;

&lt;p&gt;Let us change that to use a variable. If we ever need to change the value of the baseurl, we'll only be changing that in a single place.&lt;/p&gt;

&lt;p&gt;When you see the variables tab, you'll see a table with 3 columns. Namely VARIABLE, INITIAL VALUE, and CURRENT VALUE. Set VARIABLE = &lt;code&gt;baseUrl&lt;/code&gt;, INITIAL VALUE = &lt;code&gt;http://localhost:8090/api/v1&lt;/code&gt;, CURRENT VALUE = &lt;code&gt;http://localhost:8090/api/v1&lt;/code&gt;. INITIAL_VALUE and CURRENT_VALUE are the same here, but CURRENT_VALUE can be programmatically changed during request-response life cycle.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fd2kbulfv42d43j.cloudfront.net%2F2022%2FQ4%2Fpostman-using-collection-variables.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fd2kbulfv42d43j.cloudfront.net%2F2022%2FQ4%2Fpostman-using-collection-variables.gif" alt="Working with collection variables" width="1001" height="496"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now change all the occurrences of &lt;code&gt;http://localhost:8090/api/v1&lt;/code&gt; in the collection's URL section to &lt;code&gt;{{baseUrl}}&lt;/code&gt;. This will be a manual process, but this is worth it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Saving response data in variables
&lt;/h3&gt;

&lt;p&gt;Why would you want to save response data in a variable?&lt;/p&gt;

&lt;p&gt;That is a good question to ask. One such use case is user login. When you log in to a service, you'd get some kind of token with a certain validity time. That token is needed to make further requests. We can add a header using &lt;strong&gt;Pre-request script&lt;/strong&gt; using the variable we save.&lt;/p&gt;

&lt;p&gt;Our gingo server does not have a user authentication module right now. Let us try saving &lt;code&gt;isbn&lt;/code&gt; from a GET request.&lt;/p&gt;

&lt;p&gt;This may sound a little bit misleading, but anything you want to do after a request goes inside the &lt;strong&gt;Tests&lt;/strong&gt; tab. This also includes setting a variable for a session.&lt;/p&gt;

&lt;p&gt;Go to the &lt;strong&gt;Tests&lt;/strong&gt; section of &lt;code&gt;/books/:isbn&lt;/code&gt; and add this javascript code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;body&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;pm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="nx"&gt;pm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;collectionVariables&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;isbn&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isbn&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The code is straightforward. We are storing the JSON response in a const called &lt;code&gt;body&lt;/code&gt;. Then we access the collection variable using &lt;code&gt;pm.collectionVariables&lt;/code&gt;. We then set the variable name &lt;code&gt;isbn&lt;/code&gt; with the value of &lt;code&gt;body.isbn&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Here is me doing the same thing.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fd2kbulfv42d43j.cloudfront.net%2F2022%2FQ4%2Fpostman-saving-response-data-in-variables.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fd2kbulfv42d43j.cloudfront.net%2F2022%2FQ4%2Fpostman-saving-response-data-in-variables.gif" alt="Saving response data in variables" width="1001" height="534"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Similar to collection variables, we can set any scope of variable we discussed above.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;In this post, we saw some basic use cases of Postman. In upcoming posts, we'll see more advanced use cases. Until then, subscribe and stay updated.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Best Logging Library for Golang</title>
      <dc:creator>Santosh Kumar</dc:creator>
      <pubDate>Sun, 12 Feb 2023 11:24:47 +0000</pubDate>
      <link>https://forem.com/santosh/best-logging-library-for-golang-fe5</link>
      <guid>https://forem.com/santosh/best-logging-library-for-golang-fe5</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;I recently conducted a poll in the Go community regarding which logging library they use in their personal or professional project. The results were interesting. In this post I have jotted down the most favorite logging libraries and here is my opinion about them.&lt;/p&gt;

&lt;h2&gt;
  
  
  Poll Results
&lt;/h2&gt;

&lt;p&gt;Here are the poll results which I conducted on &lt;a href="https://www.reddit.com/r/golang/"&gt;r/golang&lt;/a&gt;, &lt;a href="https://twitter.com/i/communities/1493637136502960134"&gt;The Go Programming Language&lt;/a&gt; community on Twitter and &lt;a href="https://www.linkedin.com/in/sntshk/"&gt;my LinkedIn following&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--jYB8FOMt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://d2kbulfv42d43j.cloudfront.net/2022/Q4/reddit-poll-results.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--jYB8FOMt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://d2kbulfv42d43j.cloudfront.net/2022/Q4/reddit-poll-results.png" alt="Poll results on r/golang" width="665" height="412"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Ef1Hnizc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://d2kbulfv42d43j.cloudfront.net/2022/Q4/twitter-poll-results.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Ef1Hnizc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://d2kbulfv42d43j.cloudfront.net/2022/Q4/twitter-poll-results.png" alt="Poll results on Twitter" width="596" height="553"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--8GBfCRN3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://d2kbulfv42d43j.cloudfront.net/2022/Q4/linkedin-poll-results.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8GBfCRN3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://d2kbulfv42d43j.cloudfront.net/2022/Q4/linkedin-poll-results.png" alt="Poll results on LinkedIn" width="539" height="453"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Analysis of Results
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Selection of the candidates
&lt;/h3&gt;

&lt;p&gt;For choosing the candidates for the poll, I didn't do any thorough research. I was looking for a library to use in my &lt;a href="https://gitlab.com/nunet/device-management-service"&gt;project at work&lt;/a&gt;, and I ended up at &lt;a href="https://github.com/sirupsen/logrus"&gt;sirupsen/logrus&lt;/a&gt; which was already being used by one of the dependencies in that project. &lt;/p&gt;

&lt;p&gt;After reading the README of the logrus, I noted it was in maintenance mode and no new feature was actively being developed. I still decided to use this library because logrus is a mature project and it has all the features which a logging library should have.&lt;/p&gt;

&lt;p&gt;logrus README recommended using other libraries such as &lt;a href="https://github.com/rs/zerolog"&gt;Zerolog&lt;/a&gt;, &lt;a href="https://github.com/uber-go/zap"&gt;Zap&lt;/a&gt;, and &lt;a href="https://github.com/apex/log"&gt;Apex&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I started a poll on r/golang with these four candidates, but also came to know about &lt;a href="https://github.com/golang/glog"&gt;glog&lt;/a&gt; which was a go port of a C++ project by Google. I used that option in the poll conducted on LinkedIn. &lt;/p&gt;

&lt;p&gt;I haven't personally used any one of them yet.&lt;/p&gt;

&lt;h3&gt;
  
  
  logrus
&lt;/h3&gt;

&lt;p&gt;Let's talk about logrus first, it was the first library I landed upon when looking for one. The reason I looked at it first is that logrus was already one of the indirect dependencies of one of the dependencies in my project.&lt;/p&gt;

&lt;p&gt;logrus stands 2nd in the place. zerolog is faster than logrus but there's a reason it stands seconds among 4. It has been there for a while.&lt;/p&gt;

&lt;h3&gt;
  
  
  zerolog
&lt;/h3&gt;

&lt;p&gt;The main reason you'd want to use zerolog if you are switching from logrus is the performance. &lt;a href="https://dev.to/tags/golang/"&gt;Go&lt;/a&gt; is blazingly fast; but if your logger is making it slow, your application gets no benefit from being implemented in Go. &lt;/p&gt;

&lt;p&gt;This is what zerolog's README says:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The zerolog package provides a fast and simple logger dedicated to JSON output.&lt;/p&gt;

&lt;p&gt;Zerolog's API is designed to provide both a great developer experience and stunning performance. Its unique chaining API allows zerolog to write JSON (or CBOR) log events by avoiding allocations and reflection.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  zap
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;zap&lt;/strong&gt; is probably the most loved logging library for Go. Among &lt;strong&gt;817&lt;/strong&gt; people who have voted on r/golang, &lt;strong&gt;315&lt;/strong&gt; voted for zap.&lt;/p&gt;

&lt;p&gt;According to the stats on their GitHub, zap is the fastest logger available there. &lt;/p&gt;

&lt;p&gt;Also, zap only supports the two most recent minor versions of Go. So you might be locked with an older version of zap if your project for some reason is not able to update to the latest version of Go.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;To have an opinion, I feel that I use them all before coming to a conclusion. But after this poll, I think I'm going to start using zap right away. What is your opinion? Why factor was responsible when you were choosing your logging library. &lt;/p&gt;

</description>
      <category>go</category>
      <category>logging</category>
    </item>
    <item>
      <title>Release Dangling Elastic IPs using Lambda and Go SDK</title>
      <dc:creator>Santosh Kumar</dc:creator>
      <pubDate>Thu, 15 Sep 2022 05:42:55 +0000</pubDate>
      <link>https://forem.com/santosh/release-dangling-elastic-ips-using-lambda-and-go-sdk-39ao</link>
      <guid>https://forem.com/santosh/release-dangling-elastic-ips-using-lambda-and-go-sdk-39ao</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Today we are going to do a hands-on on how to kill a dangling EIP or in other words, deallocate an unassigned Elastic IP. But before that, let us know...&lt;/p&gt;

&lt;h2&gt;
  
  
  What is an Elastic IP and why do we need it?
&lt;/h2&gt;

&lt;p&gt;Elastic IPs are simply IP addresses provided by Amazon AWS. These are usually attached to internet gateways such as load balancers, or even EC2 instances. I have been using it with EC2 instances directly for my testing use case.&lt;/p&gt;

&lt;p&gt;Normally when you configure your EC2 instance to have a public IP but at the same time, you don't use EIP. The problem is that when you stop and start your instance, your IP address is changed. &lt;/p&gt;

&lt;p&gt;This is where Elastic IP shines. You attach an EIP to the EC2 instance and when you stop and start your instance, your IP won't be changed.&lt;/p&gt;

&lt;p&gt;This is extremely important if the EC2 you are running is hosting an internet-facing web server. Web servers shouldn't generally frequently change their IPs.&lt;/p&gt;

&lt;h2&gt;
  
  
  But why do we need an EIP killer?
&lt;/h2&gt;

&lt;p&gt;There is 1 good thing about EIP and 1 bad thing. The good thing is EIP is free to use. You don't need to pay anything for the static IP you are using. How cool! &lt;/p&gt;

&lt;p&gt;The bad thing is, that when EIP is not attached to an instance, it cost you money. How warm!&lt;/p&gt;

&lt;p&gt;It won't cost you much if you leave it detached for a few hours. But as a human, we tend to forget if EIP is in use and only get to know about it when we get our monthly bill.&lt;/p&gt;

&lt;p&gt;In the Asia Pacific (Mumbai) region, if I forget to kill an EIP for a month, I get around a $4 bill. This was my main motivation to write this article. &lt;/p&gt;

&lt;p&gt;With an EIP killer, I will be able to use Elastic IP with confidence by releasing it when not in use.&lt;/p&gt;

&lt;h2&gt;
  
  
  Get Started
&lt;/h2&gt;

&lt;p&gt;What we'll work with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;AWS Lambda&lt;/li&gt;
&lt;li&gt;Go&lt;/li&gt;
&lt;li&gt;AWS Go SDK&lt;/li&gt;
&lt;li&gt;AWS CLI&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;What we're going to do:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Run a Lambda on a predefined interval.&lt;/li&gt;
&lt;li&gt;This Lambda will use AWS SDK to check if any dangling EIP is lying around.&lt;/li&gt;
&lt;li&gt;If dangling EIP is found, deallocate, or in our language, kill it.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Initially, I was going to use Python for the Lambda runtime, but Go is faster than Python. We are going to benefit from this decision as we can run our function for a smaller time span. This is important because we plan to run our Lambda at frequent intervals.&lt;/p&gt;

&lt;p&gt;With this post, I mostly plan to expand my knowledge in the field of serverless computing. I intend to touch Lambda, EventBridge, and related constructs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Phase 1: Provision a Lambda function
&lt;/h2&gt;

&lt;p&gt;The main task in this phase is to &lt;strong&gt;manually create a function&lt;/strong&gt;. In the second phase, we'll see what is the logic for killing the EIPs. Let's get started.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Go through the web UI and choose to create a function. &lt;/li&gt;
&lt;li&gt;Keep "Author from scratch" selected.&lt;/li&gt;
&lt;li&gt;Fill in the name. I liked to call it "eip-killer".&lt;/li&gt;
&lt;li&gt;Select the runtime to be Go 1.x.&lt;/li&gt;
&lt;li&gt;Keep everything else on default. Hit &lt;strong&gt;Create function&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ljj3Hqqk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://d2kbulfv42d43j.cloudfront.net/2022/Q3/create-eip-killer-lambda.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ljj3Hqqk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://d2kbulfv42d43j.cloudfront.net/2022/Q3/create-eip-killer-lambda.png" alt="Create Lambda func from Web UI" width="709" height="600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Note: Creating Lambda with default settings also creates an IAM role. This IAM role dictates how this Lambda interacts with other AWS services. By default, this role allows Lambda to talk with CloudWatch to put logs. You can add more policies to this role when working with other AWS services.&lt;/p&gt;

&lt;p&gt;Let's go ahead and do a quick invoke to test if the function is working. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Opto_fiQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://d2kbulfv42d43j.cloudfront.net/2022/Q3/invoke-testing-a-lambda.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Opto_fiQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://d2kbulfv42d43j.cloudfront.net/2022/Q3/invoke-testing-a-lambda.png" alt="Invoke result of Lambda" width="880" height="382"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Our EIP-killer is alive. But doesn't know how to kill. Let's teach it in the next phase.&lt;/p&gt;

&lt;h2&gt;
  
  
  Phase 2: Write the EIP killing logic
&lt;/h2&gt;

&lt;p&gt;While testing, you might have got a view of the &lt;strong&gt;Code&lt;/strong&gt; tab of the function which says, "The code editor does not support the Go 1.x runtime". What this means for us developers is that we have to use our text editor to write the logic and upload the pre-built binary to Lambda.&lt;/p&gt;

&lt;p&gt;The prime documentation for Go AWS SDK is &lt;a href="https://docs.aws.amazon.com/lambda/latest/dg/lambda-golang.html"&gt;https://docs.aws.amazon.com/lambda/latest/dg/lambda-golang.html&lt;/a&gt;, but don't worry. I'll filter out the required material required for this post.&lt;/p&gt;

&lt;h3&gt;
  
  
  Phase 2.1: The initial deployment process
&lt;/h3&gt;

&lt;p&gt;Before we write the actual logic, let's write a simple "Hello EIP Killer" code to get the awareness of the process required for uploading the code.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create a workspace for our lambda code.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mkdir eip-killer
cd eip-killer
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Initialize a go module in the folder.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;go mod init EIP-killer
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You could also put the GitHub/GitLab URL of the repo where you intend to put your lambda code at.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create a main.go and put this code into it:
&lt;/li&gt;
&lt;/ol&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;main&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/aws/aws-lambda-go/lambda"&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;hello&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="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"Hello EIP Killer!"&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;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c"&gt;// Make the handler available for Remote Procedure Call by AWS Lambda&lt;/span&gt;
    &lt;span class="n"&gt;lambda&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Start&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;hello&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 we are using external dependency, get it with this command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;go get github.com/aws/aws-lambda-go/lambda
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Build a binary out of main.go:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;GOOS=linux GOARCH=amd64 go build -o main main.go
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Remember while creating the function we had selected architecture to be x86_64. So we need to reflect that with &lt;code&gt;GOARCH=amd64&lt;/code&gt;. &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Zip the binary. Upload the zip to function.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;zip main.zip main
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Upload using this command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;aws lambda update-function-code --function-name eip-killer --zip-file fileb://main.zip
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;While this could have been enough, the default handler (where lambda begins executing) in function with factory settings is &lt;code&gt;hello&lt;/code&gt;. But our code uses &lt;code&gt;main&lt;/code&gt;. So we need to update the handler config to match that. &lt;/p&gt;

&lt;p&gt;We need this update only once.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;aws lambda update-function-configuration --function-name eip-killer --handler main
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After this, when you run the func:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--LJLHCkER--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://d2kbulfv42d43j.cloudfront.net/2022/Q3/successful-deployment-of-lambda.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--LJLHCkER--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://d2kbulfv42d43j.cloudfront.net/2022/Q3/successful-deployment-of-lambda.png" alt="Updated function" width="450" height="242"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can roam around this path: &lt;a href="https://github.com/aws/aws-lambda-go"&gt;https://github.com/aws/aws-lambda-go&lt;/a&gt; if you want to dig deeper into Go+Lambda. But for now, I'm going to use AWS SDK to do our magic.&lt;/p&gt;

&lt;h3&gt;
  
  
  Phase 2.2: Logic to deallocate unused EIPs
&lt;/h3&gt;

&lt;p&gt;Open up the main.go again and write this:&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;main&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;"fmt"&lt;/span&gt;
    &lt;span class="s"&gt;"log"&lt;/span&gt;

    &lt;span class="s"&gt;"github.com/aws/aws-lambda-go/lambda"&lt;/span&gt;
    &lt;span class="s"&gt;"github.com/aws/aws-sdk-go-v2/config"&lt;/span&gt;
    &lt;span class="s"&gt;"github.com/aws/aws-sdk-go-v2/service/ec2"&lt;/span&gt;
    &lt;span class="s"&gt;"github.com/aws/aws-sdk-go-v2/service/ec2/types"&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;MyEvent&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="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;Handler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&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;name&lt;/span&gt; &lt;span class="n"&gt;MyEvent&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="c"&gt;// Load the Shared AWS Configuration (~/.aws/config)&lt;/span&gt;
    &lt;span class="n"&gt;cfg&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;config&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LoadDefaultConfig&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="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="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="c"&gt;// Create an Amazon EC2 service client&lt;/span&gt;
    &lt;span class="n"&gt;ec2ServiceClient&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;ec2&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewFromConfig&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cfg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c"&gt;// DescribeAddressesInput with no filter means list all addresses&lt;/span&gt;
    &lt;span class="n"&gt;IpListFilter&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;ec2&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DescribeAddressesInput&lt;/span&gt;&lt;span class="p"&gt;{}&lt;/span&gt;

    &lt;span class="c"&gt;// Ask the EC2 client to list all Elastic IPs.&lt;/span&gt;
    &lt;span class="n"&gt;result&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;ec2ServiceClient&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DescribeAddresses&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;TODO&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;IpListFilter&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;fmt&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;"Got an error retrieving information about your Amazon Elastic IPs:"&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="c"&gt;// Out of all IPs, check if they have an allocation ID. If not, they are a candidate for deletion&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="k"&gt;range&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Addresses&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;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Allocation ID: "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AllocationId&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;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Public IP: "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PublicIp&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="c"&gt;// if this EIP is not associated with any AWS resources, proceed with killing.&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AssociationId&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="c"&gt;// extra step for flexibility&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;isThisEIPKillable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Tags&lt;/span&gt;&lt;span class="p"&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;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"About to be killed"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="c"&gt;// Release/kill the Elastic IP&lt;/span&gt;
                &lt;span class="n"&gt;ReleaseAddressFilter&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;ec2&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ReleaseAddressInput&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;AllocationId&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AllocationId&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
                &lt;span class="n"&gt;ec2ServiceClient&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ReleaseAddress&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;TODO&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;ReleaseAddressFilter&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;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PublicIp&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;" is not more"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&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;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PublicIp&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;" has KILLERHOLD enabled and is going to stay"&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;else&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;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Association ID: "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AssociationId&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;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Instance ID: "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;InstanceId&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;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"PrivateIpAddress: "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PrivateIpAddress&lt;/span&gt;&lt;span class="p"&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;Println&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="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"Done execution"&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="c"&gt;// isThisEIPKillable scans to tags of Elastic IP and only returns false when&lt;/span&gt;
&lt;span class="c"&gt;// EIPKILLER is tag is set to true.&lt;/span&gt;
&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;isThisEIPKillable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tags&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="n"&gt;types&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Tag&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="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tag&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="k"&gt;range&lt;/span&gt; &lt;span class="n"&gt;tags&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;tag&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Key&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s"&gt;"KILLERHOLD"&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;tag&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Value&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s"&gt;"true"&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="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="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;lambda&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Start&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Handler&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;Quite a large source code. Let us understand it line by line.&lt;/p&gt;

&lt;p&gt;Line 14-16 declares an event struct. This struct is going to be a parameter to the Handler function.&lt;/p&gt;

&lt;p&gt;On line 18, we see function with signature &lt;code&gt;Handler(ctx context.Context, name MyEvent) (string, error)&lt;/code&gt;. &lt;code&gt;Handler&lt;/code&gt; here is the name of the function.&lt;/p&gt;

&lt;p&gt;The first parameter to the handler is the context object. If you are working with web services in golang, you must be aware of that.&lt;/p&gt;

&lt;p&gt;Next is our &lt;code&gt;MyEvent&lt;/code&gt; which is defined above. This is as per Lambda's spec.&lt;/p&gt;

&lt;p&gt;Our handler function also returns a string and an error. Which is then bubbled to Lambda logs.&lt;/p&gt;

&lt;p&gt;Line 20 deals with configuration. Please note that we are using AWS SDK. And the SDK can run on platforms other than Lambda. On the local system, the default config is located at ~/.aws/config. But on Lambda, it automatically loads the region it's running in. &lt;/p&gt;

&lt;p&gt;On line 26 we create a new EC2 client to interact with our AWS account. We initialize this client with the config instance we created on line 15.&lt;/p&gt;

&lt;p&gt;On line 29 we have initialized a filter for IPs. This seems to be an added step. But this variable is going to be a mandatory parameter for our next command.&lt;/p&gt;

&lt;p&gt;On line 32 we get a list of all Elastic IPs associated with our account. There are no filters to the result as we have not specified any filter on line 29.&lt;/p&gt;

&lt;p&gt;It's time to look at the &lt;code&gt;isThisEIPKillable&lt;/code&gt; function which is from 69 to 76. This is an extra feature for flexibility. This will forgive any EIP which has the tag &lt;code&gt;KILLERHOLD&lt;/code&gt; set to &lt;code&gt;true&lt;/code&gt;. So when you have an EIP you don't want to kill, you set this tag to it. This is good for the experiment as our Lambda will be running on a 1 hours (configurable by user) interval and it might not be desired outcome to delete them every 1 hour.&lt;/p&gt;

&lt;p&gt;Let us get back to our main flow. We have a &lt;code&gt;result&lt;/code&gt; variable with all the addresses in it. On line 40 we check if the IP is associated with any EC2 or not. Then we run the helper function we just discussed. If all is okay, meaning that KIP can be released, we go ahead and release the address back to the AWS pool.&lt;/p&gt;

&lt;p&gt;On lines 57-59, if EIP is associated with any EC2, we print some metadata about the EIP association.&lt;/p&gt;

&lt;p&gt;That's it. It was not that hard to understand, isn't it? Before we deploy it, let's create some EIP and not allocate it to any EC2. We'll also have some EIP having KILLERHOLD set to true.&lt;/p&gt;

&lt;h3&gt;
  
  
  Phase 2.3: Test our EIP killer Give Lambda permission to release and read EIPs
&lt;/h3&gt;

&lt;p&gt;I hope you have updated your lambda function and pushed the zip file to the function. Review Phase 2.1 if you have not. Continue reading if you did.&lt;/p&gt;

&lt;p&gt;Before I test it with actual EIPs, I wanted to show something else. Right now if you try to test the function, you'd see something like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Kxz8zDeN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://d2kbulfv42d43j.cloudfront.net/2022/Q3/403-on-lambda.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Kxz8zDeN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://d2kbulfv42d43j.cloudfront.net/2022/Q3/403-on-lambda.png" alt="403 on Lambda" width="880" height="336"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you clearly read the error message, it says that API call returned 403. Meaning that Lambda was not authorized to make the call to EIP APIs.&lt;/p&gt;

&lt;p&gt;To overcome this problem, we need to give access to Lambda to read some metadata from EC2.&lt;/p&gt;

&lt;p&gt;When no Lambda Web UI for the function. If you go to Configuration &amp;gt; Permission &amp;gt; Execution role as described in the image below. You'll see a role that was created while we created the function.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--3QscOQOo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://d2kbulfv42d43j.cloudfront.net/2022/Q3/lambda-functions-role.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--3QscOQOo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://d2kbulfv42d43j.cloudfront.net/2022/Q3/lambda-functions-role.png" alt="Execution role config for Lambda" width="727" height="457"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click on that and you'll be taken to the IAM page for that role. &lt;/p&gt;

&lt;p&gt;When on that page, look for a dropdown named &lt;strong&gt;Add permissions&lt;/strong&gt; and click on &lt;em&gt;Create inline policy&lt;/em&gt;. &lt;/p&gt;

&lt;p&gt;Switch from &lt;strong&gt;Visual editor&lt;/strong&gt; to &lt;strong&gt;JSON&lt;/strong&gt;. And paste this policy.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"Version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2012-10-17"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"Statement"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"Sid"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"VisualEditor0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"Effect"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Allow"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"Action"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="s2"&gt;"ec2:ReleaseAddress"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="s2"&gt;"ec2:DescribeAddresses"&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"Resource"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"*"&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see, in the &lt;em&gt;Action&lt;/em&gt; section, we have added permission for &lt;code&gt;ec2:ReleaseAddress&lt;/code&gt;, and &lt;code&gt;ec2:DescribeAddresses&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Review policy&lt;/em&gt; and give it a name, and then &lt;em&gt;Create policy&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;When done, you'd see this policy in the list of policies attached to the role.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--MgVe2ue2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://d2kbulfv42d43j.cloudfront.net/2022/Q3/inline-policy-attached-to-role.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--MgVe2ue2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://d2kbulfv42d43j.cloudfront.net/2022/Q3/inline-policy-attached-to-role.png" alt="Inline policy attached to role" width="673" height="449"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Phase 2.3: Test our EIP killer
&lt;/h3&gt;

&lt;p&gt;We are not set for the actual testing.&lt;/p&gt;

&lt;p&gt;We are going to allocate 3 Elastic IPs for our testing purpose. &lt;/p&gt;

&lt;p&gt;One we'll attach to the EC2 instance.&lt;/p&gt;

&lt;p&gt;The second will be dangling. &lt;/p&gt;

&lt;p&gt;And the third one will be also dangling but will have our KILLERHOLD set to true.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--GYpd7756--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://d2kbulfv42d43j.cloudfront.net/2022/Q3/eip-as-test-subject.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--GYpd7756--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://d2kbulfv42d43j.cloudfront.net/2022/Q3/eip-as-test-subject.png" alt="EIP set for testing" width="663" height="291"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To actually invoke the function (apart from testing it), one way is to create a public URL. We can also invoke through the AWS CLI, but I'm not choosing that for now. You can do it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--aSAinIiX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://d2kbulfv42d43j.cloudfront.net/2022/Q3/create-a-public-url-for-lambda.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--aSAinIiX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://d2kbulfv42d43j.cloudfront.net/2022/Q3/create-a-public-url-for-lambda.gif" alt="Create a public URL for lambda" width="880" height="448"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then I went ahead and opened that URL to execute the function. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ZrTKDUwe--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://d2kbulfv42d43j.cloudfront.net/2022/Q3/eip-killer-executed.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ZrTKDUwe--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://d2kbulfv42d43j.cloudfront.net/2022/Q3/eip-killer-executed.png" alt="Lambda invoked by visiting public URL" width="483" height="111"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can configure AWS API Gateway in front of the function. But that's out of the scope of this post.&lt;/p&gt;

&lt;p&gt;Next, we see the result of the invocation.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--jqzJl_w5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://d2kbulfv42d43j.cloudfront.net/2022/Q3/now-we-only-have-2-eip.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--jqzJl_w5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://d2kbulfv42d43j.cloudfront.net/2022/Q3/now-we-only-have-2-eip.png" alt="Result after EIP Killer execution" width="421" height="250"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That's the end of Phase 2. We can kill EIPs now. How wonderful.&lt;/p&gt;

&lt;h2&gt;
  
  
  Phase 3: Trigger Lambda at a 1-hour interval
&lt;/h2&gt;

&lt;p&gt;The main part of the EIP killer is already developed. Let's now execute it at a 1-hour interval as planned before.&lt;/p&gt;

&lt;h3&gt;
  
  
  Phase 3.1: Configure EventBridge aka CloudWatch Events
&lt;/h3&gt;

&lt;p&gt;We are going to emit an event at our 1-hour interval and we are going to use EventBridge for this.&lt;/p&gt;

&lt;p&gt;I have recorded a screencast gif to preserve some space on this post.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--viQCTsOX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://d2kbulfv42d43j.cloudfront.net/2022/Q3/eventbridge-emit-event-1-hour.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--viQCTsOX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://d2kbulfv42d43j.cloudfront.net/2022/Q3/eventbridge-emit-event-1-hour.gif" alt="Configure EventBridge to emit event on 1 hour" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once done, this event should appear in the &lt;strong&gt;Trigger&lt;/strong&gt; section of the Lambda function; as seen in the below image &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--agKryJJf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://d2kbulfv42d43j.cloudfront.net/2022/Q3/lambda-trigger-configuration.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--agKryJJf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://d2kbulfv42d43j.cloudfront.net/2022/Q3/lambda-trigger-configuration.png" alt="Trigger config showing EventBridge rule" width="837" height="523"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Phase 3.2: Create an EIP and go to sleep
&lt;/h3&gt;

&lt;p&gt;As I'm writing this post at 4 am. I'm going to create an EIP and go to sleep. Will check in the morning if our setup is working.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;A few hours later&lt;/em&gt;...&lt;/p&gt;

&lt;p&gt;I woke up this morning with only 1 EIP. &lt;/p&gt;

&lt;p&gt;And this is how we gonna achieve this killing at 1 hour. You can configure the interval, but I think this is optimal. You also don't need to have a public IP for this. So if you have, you can delete it now from the web interface.&lt;/p&gt;

</description>
      <category>lambda</category>
      <category>go</category>
      <category>cloud</category>
    </item>
    <item>
      <title>How to Integrate Swagger UI in Go Backend - Gin Edition</title>
      <dc:creator>Santosh Kumar</dc:creator>
      <pubDate>Mon, 30 May 2022 07:08:42 +0000</pubDate>
      <link>https://forem.com/santosh/how-to-integrate-swagger-ui-in-go-backend-gin-edition-2cbd</link>
      <guid>https://forem.com/santosh/how-to-integrate-swagger-ui-in-go-backend-gin-edition-2cbd</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Unlike FastAPI, Gin does not have OpenAPI integration built in. With FastAPI when you add a route, documentation is already generated. With Gin, this is not the case. But recently I integrated Swagger UI in one of my Go backends and I wanted to document that process.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;An already existing Gin server&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You might consider &lt;a href="https://dev.to/posts/2022/building-a-bookstore-api-in-golang-with-gin/"&gt;Building a Book Store API in Golang With Gin&lt;/a&gt; if you are starting from scratch. I'll be using the same book store and extending over it to integrate Swagger UI.&lt;/p&gt;

&lt;h2&gt;
  
  
  How Swagger works with Gin
&lt;/h2&gt;

&lt;p&gt;The way Swagger works with other Go backend is not different they all have the same mechanism. But how does it really work and what do we have to really do?&lt;/p&gt;

&lt;p&gt;Swagger uses the Go comment system which is very well integrated with documentation already as we know. We write comments in a pre-defined way, details of which we will see further ahead in the post. But mostly it is divided into 2 parts. The server itself and the routes.&lt;/p&gt;

&lt;p&gt;Swagger has a CLI binary which when runs converts these comment documents into OpenAPI compliant documentation. The resultant file also includes OpenAPI server specs in JSON and YAML format.&lt;/p&gt;

&lt;p&gt;Lastly, we route the generated content via a handler in our backend.&lt;/p&gt;

&lt;p&gt;How do we do that? Let's see.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setup Swagger CLI
&lt;/h2&gt;

&lt;p&gt;The prime repository you should keep under your pillow is &lt;a href="https://github.com/swaggo/swag" rel="noopener noreferrer"&gt;https://github.com/swaggo/swag&lt;/a&gt;. Both in terms of CLI and documentation.&lt;/p&gt;

&lt;p&gt;We'll install a CLI application called &lt;code&gt;swag&lt;/code&gt;. Here's how:&lt;/p&gt;

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

go get -u github.com/swaggo/swag/cmd/swag

# 1.16 or newer
go install github.com/swaggo/swag/cmd/swag@latest


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The first command will download the dependencies to integrate in the server application.&lt;/p&gt;

&lt;p&gt;The second one is where we install the CLI.&lt;/p&gt;

&lt;p&gt;Now you should be able to run the swag command:&lt;/p&gt;

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

$ swag -h
NAME:
   swag - Automatically generate RESTful API documentation with Swagger 2.0 for Go.

USAGE:
   swag [global options] command [command options] [arguments...]

VERSION:
   v1.8.1

COMMANDS:
   init, i  Create docs.go
   fmt, f   format swag comments
   help, h  Shows a list of commands or help for one command

GLOBAL OPTIONS:
   --help, -h     show help (default: false)
   --version, -v  print the version (default: false)



&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
  
  
  Documenting the Gin Server
&lt;/h2&gt;

&lt;p&gt;When you look at Swagger UI documentation for any OpenAPI enabled website, you'd see something like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fd2kbulfv42d43j.cloudfront.net%2F2022%2FQ2%2Fsample-swagger-ui-documentation.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fd2kbulfv42d43j.cloudfront.net%2F2022%2FQ2%2Fsample-swagger-ui-documentation.png" alt="Petstore Swagger UI Docs"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You might be familiar with the low half part of the UI. This is what Swagger docs are for i.e. to document the routes.&lt;/p&gt;

&lt;p&gt;But before we deal with the lower 50% part I want you to notice in the above picture is the top 50% part. Right from the &lt;strong&gt;Swagger Petstore&lt;/strong&gt; header to &lt;strong&gt;Find out more about the Swagger&lt;/strong&gt; anchor link.&lt;/p&gt;

&lt;p&gt;This part shows the metadata about the API server itself. In this section, we are going to build that part. You can find the &lt;a href="https://github.com/santosh/gingo/tree/91cafb5e19f3bbc3be9135ba74f8883d74941651" rel="noopener noreferrer"&gt;code to start with here&lt;/a&gt;. We'll be continuing on that code.&lt;/p&gt;

&lt;p&gt;First of all, we need to go get the packages we need to work with:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;go get -u github.com/swaggo/files
go get -u github.com/swaggo/gin-swagger
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Now after we have done that, let's look at our main.go file. This is the &lt;code&gt;main.go&lt;/code&gt; at the moment:&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;main&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="s"&gt;"github.com/santosh/gingo/routes"&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;router&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;routes&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SetupRouter&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="n"&gt;router&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;":8080"&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;h3&gt;
  
  
  Add a route for Swagger Docs
&lt;/h3&gt;

&lt;p&gt;We add a new router in the main function:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;router.GET("/docs/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The modified file would look like this:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;&lt;span class="err"&gt;

&lt;/span&gt;&lt;span class="gd"&gt;-import "github.com/santosh/gingo/routes"
&lt;/span&gt;&lt;span class="gi"&gt;+import (
+       "github.com/santosh/gingo/routes"
+       swaggerFiles "github.com/swaggo/files"
+       ginSwagger "github.com/swaggo/gin-swagger"
+)
&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt; func main() {
        router := routes.SetupRouter()
&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="gi"&gt;+       router.GET("/docs/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))
+
&lt;/span&gt;        router.Run(":8080")
 }
&lt;span class="err"&gt;

&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;code&gt;swaggerFiles.Handler&lt;/code&gt; here is the handler which has all the assets embedded in it. Assets like the HTML, CSS, and javascript files are shown on the documentation end.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;ginSwagger.WrapHandler&lt;/code&gt; is a wrapper around &lt;code&gt;http.Handler&lt;/code&gt;, but for Gin.&lt;/p&gt;

&lt;p&gt;This should be enough for testing. Let's see how the docs render at &lt;code&gt;&amp;lt;server address&amp;gt;/docs/index.html&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fd2kbulfv42d43j.cloudfront.net%2F2022%2FQ2%2Ffailed-to-load-api-definition.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fd2kbulfv42d43j.cloudfront.net%2F2022%2FQ2%2Ffailed-to-load-api-definition.png" alt="Docs loaded, API definition didn't load"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The good news is API documentation site is up. The bad news is it does not look like a normal API documentation site. What did we miss?&lt;/p&gt;

&lt;h3&gt;
  
  
  Generate swagger docs every time you modify doc string
&lt;/h3&gt;

&lt;p&gt;Swagger documentation is stored in Go's own docstring. We have a special syntax that we follow. More on that later. But first, let us learn how to generate docs.&lt;/p&gt;

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

$ swag init
2022/05/25 23:59:16 Generate swagger docs....
2022/05/25 23:59:16 Generate general API Info, search dir:./
2022/05/25 23:59:16 create docs.go at  docs/docs.go
2022/05/25 23:59:16 create swagger.json at  docs/swagger.json
2022/05/25 23:59:16 create swagger.yaml at  docs/swagger.yaml


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;We run &lt;code&gt;swag init&lt;/code&gt; every time we update docs for our API. This generates 3 files inside a sub directory called &lt;code&gt;docs/&lt;/code&gt;.&lt;/p&gt;

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

$ tree docs
docs
├── docs.go
├── swagger.json
└── swagger.yaml

0 directories, 3 files


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;code&gt;swagger.json&lt;/code&gt; and &lt;code&gt;swagger.yaml&lt;/code&gt; are the actual specification which you can upload to services like AWS API Gateway and similar services. &lt;code&gt;docs.go&lt;/code&gt; is a glue code that we need to import into our server.&lt;/p&gt;

&lt;p&gt;Let us now import the documentation to our main.go.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;&lt;span class="err"&gt;

&lt;/span&gt; package main
&lt;span class="err"&gt;
&lt;/span&gt; import (
&lt;span class="gi"&gt;+       _ "github.com/santosh/gingo/docs"
&lt;/span&gt;        "github.com/santosh/gingo/routes"
        swaggerFiles "github.com/swaggo/files"
        ginSwagger "github.com/swaggo/gin-swagger"
 )
&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="gi"&gt;+// @title     Gingo Bookstore API
&lt;/span&gt; func main() {
        router := routes.SetupRouter()
&lt;span class="err"&gt;

&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;As you can see we have imported &lt;code&gt;docs&lt;/code&gt; the module by giving the full path of the module. We also have to prepend this import using &lt;code&gt;_&lt;/code&gt; because it is not explicitly used in main.go file.&lt;/p&gt;

&lt;p&gt;You might also have noticed &lt;code&gt;// @title     Gingo Bookstore API&lt;/code&gt; line. Please note its position as this is important. It is just above the &lt;code&gt;main()&lt;/code&gt; func. Also &lt;code&gt;@title&lt;/code&gt; is not random here. It is one of the keywords which is documented under &lt;a href="https://github.com/swaggo/swag#general-api-info" rel="noopener noreferrer"&gt;General API Info&lt;/a&gt;. We'll see more of these as we go, but for now, let's regenerate our docs and review the API docs.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fd2kbulfv42d43j.cloudfront.net%2F2022%2FQ2%2Fswagger-ui-with-title-only.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fd2kbulfv42d43j.cloudfront.net%2F2022%2FQ2%2Fswagger-ui-with-title-only.png" alt="Working API Docs"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Looks like we are getting somewhere. :D&lt;/p&gt;

&lt;h2&gt;
  
  
  Add General API Info to Gin API Server
&lt;/h2&gt;

&lt;p&gt;We saw &lt;code&gt;@title&lt;/code&gt; annotation in the last section. It is used to set the title for the API server. But it is not the only annotation available. There is &lt;a href="https://github.com/swaggo/swag#general-api-info" rel="noopener noreferrer"&gt;a wide array of annotation in Swagger&lt;/a&gt;. You can find them in use &lt;a href="https://github.com/swaggo/swag/blob/master/example/celler/main.go#L16-L57" rel="noopener noreferrer"&gt;in real life here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I'm going to use some of them to construct metadata on my doc site.&lt;/p&gt;

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

// @title           Gin Book Service
// @version         1.0
// @description     A book management service API in Go using Gin framework.
// @termsOfService  https://tos.santoshk.dev

// @contact.name   Santosh Kumar
// @contact.url    https://twitter.com/sntshk
// @contact.email  sntshkmr60@gmail.com

// @license.name  Apache 2.0
// @license.url   http://www.apache.org/licenses/LICENSE-2.0.html

// @host      localhost:8080
// @BasePath  /api/v1


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;ol&gt;
&lt;li&gt;Run &lt;code&gt;swag init&lt;/code&gt;. &lt;/li&gt;
&lt;li&gt;Re-run the server.&lt;/li&gt;
&lt;li&gt;Check for update:&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fd2kbulfv42d43j.cloudfront.net%2F2022%2FQ2%2Fswagger-api-server-with-metadata.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fd2kbulfv42d43j.cloudfront.net%2F2022%2FQ2%2Fswagger-api-server-with-metadata.png" alt="Swagger API Server with Metadata"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That's some metadata in there. &lt;/p&gt;

&lt;p&gt;You might also have noticed that the API spec inside docs/ directory has changed. For example, here is the &lt;code&gt;swagger.yaml&lt;/code&gt; file from the &lt;code&gt;docs/&lt;/code&gt; dir.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;&lt;span class="err"&gt;

&lt;/span&gt; {
     "swagger": "2.0",
     "info": {
&lt;span class="gd"&gt;-        "title": "Gingo Bookstore API",
-        "contact": {}
&lt;/span&gt;&lt;span class="gi"&gt;+        "description": "A book management service API in Go using Gin framework.",
+        "title": "Gin Book Service",
+        "termsOfService": "https://tos.santoshk.dev",
+        "contact": {
+            "name": "Santosh Kumar",
+            "url": "https://twitter.com/sntshk",
+            "email": "sntshkmr60@gmail.com"
+        },
+        "license": {
+            "name": "Apache 2.0",
+            "url": "http://www.apache.org/licenses/LICENSE-2.0.html"
+        },
+        "version": "1.0"
&lt;/span&gt;     },
&lt;span class="gi"&gt;+    "host": "localhost:8080",
+    "basePath": "/api/v1",
&lt;/span&gt;     "paths": {}
 }
&lt;span class="err"&gt;

&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Now it's time to add docs for API endpoints.&lt;/p&gt;

&lt;h2&gt;
  
  
  Add API Operation Info to API Endpoints
&lt;/h2&gt;

&lt;p&gt;Just like General API Info for the main server, there also is &lt;a href="https://github.com/swaggo/swag#api-operation" rel="noopener noreferrer"&gt;API Operation&lt;/a&gt; for individual routes/endpoints handlers.&lt;/p&gt;

&lt;p&gt;They are more diverse than what I'm going to use here. The ones I'm going to use are just a subset of them. If you want to check out some real examples, you can &lt;a href="https://github.com/swaggo/swag/tree/master/example/celler/controller" rel="noopener noreferrer"&gt;find them here&lt;/a&gt; on each of the route handlers.&lt;/p&gt;

&lt;p&gt;Here is modified &lt;code&gt;handlers/books.go&lt;/code&gt;:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;&lt;span class="err"&gt;

&lt;/span&gt;        "github.com/santosh/gingo/models"
 )
&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="gd"&gt;-// GetBooks responds with the list of all books as JSON.
&lt;/span&gt;&lt;span class="gi"&gt;+// GetBooks             godoc
+// @Summary      Get books array
+// @Description  Responds with the list of all books as JSON.
+// @Tags         books
+// @Produce      json
+// @Success      200  {array}  models.Book
+// @Router       /books [get]
&lt;/span&gt; func GetBooks(c *gin.Context) {
        c.JSON(http.StatusOK, db.Books)
 }
&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="gd"&gt;-// PostBook takes a book JSON and store in DB.
&lt;/span&gt;&lt;span class="gi"&gt;+// PostBook             godoc
+// @Summary      Store a new book
+// @Description  Takes a book JSON and store in DB. Return saved JSON.
+// @Tags         books
+// @Produce      json
+// @Param        book  body      models.Book  true  "Book JSON"
+// @Success      200   {object}  models.Book
+// @Router       /books [post]
&lt;/span&gt; func PostBook(c *gin.Context) {
        var newBook models.Book
&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="p"&gt;@@ -28,7 +41,14 @@&lt;/span&gt; func PostBook(c *gin.Context) {
        c.JSON(http.StatusCreated, newBook)
 }
&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="gd"&gt;-// GetBookByISBN locates the book whose ISBN value matches the isbn
&lt;/span&gt;&lt;span class="gi"&gt;+// GetBookByISBN                godoc
+// @Summary      Get single book by isbn
+// @Description  Returns the book whose ISBN value matches the isbn.
+// @Tags         books
+// @Produce      json
+// @Param        isbn  path      string  true  "search book by isbn"
+// @Success      200  {object}  models.Book
+// @Router       /books/{isbn} [get]
&lt;/span&gt; func GetBookByISBN(c *gin.Context) {
        isbn := c.Param("isbn")
&lt;span class="err"&gt;

&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;ol&gt;
&lt;li&gt;Run &lt;code&gt;swag init&lt;/code&gt;. &lt;/li&gt;
&lt;li&gt;Re-run the server.&lt;/li&gt;
&lt;li&gt;Check for updates:&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fd2kbulfv42d43j.cloudfront.net%2F2022%2FQ2%2Fswagger-ui-routes-documented.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fd2kbulfv42d43j.cloudfront.net%2F2022%2FQ2%2Fswagger-ui-routes-documented.png" alt="Swagger UI; with documented routes"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And here is the updated &lt;code&gt;swagger.yaml&lt;/code&gt;:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;&lt;span class="err"&gt;

&lt;/span&gt; basePath: /api/v1
&lt;span class="gi"&gt;+definitions:
+  models.Book:
+    properties:
+      author:
+        type: string
+      isbn:
+        type: string
+      title:
+        type: string
+    type: object
&lt;/span&gt; host: localhost:8080
 info:
   contact:
&lt;span class="p"&gt;@@ -12,5 +22,58 @@&lt;/span&gt; info:
   termsOfService: https://tos.santoshk.dev
   title: Gin Book Service
   version: "1.0"
&lt;span class="gd"&gt;-paths: {}
&lt;/span&gt;&lt;span class="gi"&gt;+paths:
+  /books:
+    get:
+      description: Responds with the list of all books as JSON.
+      produces:
+      - application/json
+      responses:
+        "200":
+          description: OK
+          schema:
+            items:
+              $ref: '#/definitions/models.Book'
+            type: array
+      summary: Get books array
+      tags:
+      - books
+    post:
+      description: Takes a book JSON and store in DB. Return saved JSON.
+      parameters:
+      - description: Book JSON
+        in: body
+        name: book
+        required: true
+        schema:
+          $ref: '#/definitions/models.Book'
+      produces:
+      - application/json
+      responses:
+        "200":
+          description: OK
+          schema:
+            $ref: '#/definitions/models.Book'
+      summary: Store a new book
+      tags:
+      - books
+  /books/{isbn}:
+    get:
+      description: Returns the book whose ISBN value matches the isbn.
+      parameters:
+      - description: search book by isbn
+        in: path
+        name: isbn
+        required: true
+        type: string
+      produces:
+      - application/json
+      responses:
+        "200":
+          description: OK
+          schema:
+            $ref: '#/definitions/models.Book'
+      summary: Get single book by isbn
+      tags:
+      - books
&lt;/span&gt; swagger: "2.0"
&lt;span class="err"&gt;

&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Notice the new &lt;code&gt;definitions&lt;/code&gt; and &lt;code&gt;paths&lt;/code&gt; section added. It is for models and the endpoints respectively.&lt;/p&gt;

&lt;h2&gt;
  
  
  Bonus: Router Group for /api/v1
&lt;/h2&gt;

&lt;p&gt;It is always a good idea to prepend your routes with &lt;code&gt;api/v1&lt;/code&gt;. &lt;code&gt;v1&lt;/code&gt; bit has a logic behind it. It is for the time when you have to introduce a breaking change which is not backward compatible. Maybe the input or the output has changes that might break millions of dependent client.&lt;/p&gt;

&lt;p&gt;In these situations, you increment the version to something like &lt;code&gt;api/v2&lt;/code&gt; and let the older API server serve old from the old handler.&lt;/p&gt;

&lt;p&gt;Right now all of the routes in gingo server start with &lt;code&gt;/book&lt;/code&gt;. We are going to change that.&lt;/p&gt;

&lt;p&gt;Here is the modified &lt;code&gt;routes/routes.go&lt;/code&gt;.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;&lt;span class="err"&gt;


&lt;/span&gt; func SetupRouter() *gin.Engine {
        router := gin.Default()
&lt;span class="gd"&gt;-       router.GET("/books", handlers.GetBooks)
-       router.GET("/books/:isbn", handlers.GetBookByISBN)
-       // router.DELETE("/books/:isbn", handlers.DeleteBookByISBN)
-       // router.PUT("/books/:isbn", handlers.UpdateBookByISBN)
-       router.POST("/books", handlers.PostBook)
&lt;/span&gt;&lt;span class="gi"&gt;+
+       v1 := router.Group("/api/v1")
+       {
+               v1.GET("/books", handlers.GetBooks)
+               v1.GET("/books/:isbn", handlers.GetBookByISBN)
+               // router.DELETE("/books/:isbn", handlers.DeleteBookByISBN)
+               // router.PUT("/books/:isbn", handlers.UpdateBookByISBN)
+               v1.POST("/books", handlers.PostBook)
+       }
&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;        return router
 }
&lt;span class="err"&gt;

&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Here we use &lt;code&gt;router.Group&lt;/code&gt; to create a group with a path of &lt;code&gt;/api/v1&lt;/code&gt;. We then move all the route definitions into the group and surround it with braces. That is how we create a path route in Gin.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;API documentation is an essential part of API documentation. Instead of documenting the endpoints anywhere else, we can document the routes right in the code. That way we only have 1 single source of truth. No need to maintain code and documentation separately. In turn, we get always up-to-date documentation.&lt;/p&gt;

&lt;p&gt;Every backend server has some sort of support for Swagger UI. I have covered the basics for Gin, but if you use any other framework, I encourage you to look for your own framework.&lt;/p&gt;

</description>
      <category>swagger</category>
      <category>go</category>
      <category>gin</category>
      <category>openapi</category>
    </item>
    <item>
      <title>gRPC for Absolute Beginners, in Go</title>
      <dc:creator>Santosh Kumar</dc:creator>
      <pubDate>Sat, 28 May 2022 15:43:57 +0000</pubDate>
      <link>https://forem.com/santosh/grpc-for-absolute-beginners-in-go-29hp</link>
      <guid>https://forem.com/santosh/grpc-for-absolute-beginners-in-go-29hp</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;The Internet has evolved in the last 2 decades a lot. HTTP/1.1 was not enough so we have HTTP2 now. The specification we used to transfer data between the client and the server has also evolved. From XML to JSON, now we have Protocol Buffer, which is a binary spec. Let's dive deeper.&lt;/p&gt;

&lt;p&gt;The picture below from Wikipedia shows how exponential data is growing.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ymNQNqrE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://upload.wikimedia.org/wikipedia/commons/7/7c/Hilbert_InfoGrowth.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ymNQNqrE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://upload.wikimedia.org/wikipedia/commons/7/7c/Hilbert_InfoGrowth.png" alt="Growth of data" width="880" height="660"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Go&lt;/li&gt;
&lt;li&gt;HTTP2&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Enough HTTP2 to know gRPC
&lt;/h2&gt;

&lt;p&gt;During the early days of the web, we only had static content, hardly text files, and HTML files. After then, the web grew a bit and the web server and clients started to deal with rich media like rich texts, images, and videos. Servers also started to serve dynamic content based on what clients request.&lt;/p&gt;

&lt;p&gt;This was the start of the RPC era. A client would hit a certain endpoint with certain data, and the server's work was to respond to that request. In the early time of RPC, XML was extensively used. We still use XML in some systems. But most of the world has moved to JSON as a communication format between the server and the client.&lt;/p&gt;

&lt;p&gt;Now, over time, everything has evolved. One of the things which evolved is HTTP spec. Now we have HTTP2. HTTP2 is the base of gRPC. Certain properties make HTTP2 a nurturing ground for gRPC.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;HTTP/1.1&lt;/th&gt;
&lt;th&gt;HTTP/2&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Header is plaintext and not compressed&lt;/td&gt;
&lt;td&gt;Header is compressed and binary&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Spawns a new TCP connection on each request&lt;/td&gt;
&lt;td&gt;uses already existing TCP connection&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TLS is not required&lt;/td&gt;
&lt;td&gt;Requires TLS by default, enhanced security&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Let's learn about Protocol Buffer first
&lt;/h2&gt;

&lt;p&gt;We have seen how HTTP2 is essential for gRPC, now let's see where Protocol Buffer stands.&lt;/p&gt;

&lt;p&gt;Although you can use gRPC with JSON, Protocol Buffer brings new things to the table. We saw that for a long time, JSON was used to send data back and forth between servers and clients. Now, what has happened is that we have taken yet another step to move from JSON to its successor.&lt;/p&gt;

&lt;p&gt;Protocol buffers are building block of gRPC and is a replacement for JSON. Protocol Buffer inherits a lot from HTTP/2.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;JSON&lt;/th&gt;
&lt;th&gt;Protocol Buffer&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Plaintext&lt;/td&gt;
&lt;td&gt;Binary&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Larger payload over wire&lt;/td&gt;
&lt;td&gt;Smaller payload over wire&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Write your server&lt;/td&gt;
&lt;td&gt;.proto files can create server stub&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;As we already know, HTTP/2 is binary. So are protocol buffers. Now you don't need to pass a date as a string in JSON. You can pass BSON over the wire.&lt;/li&gt;
&lt;li&gt;It is easy on a network as we only use the space we need to use. Say int32 only uses 4 bytes of data. The same data in JSON (string) could have used multiple bytes for a longer integer value.&lt;/li&gt;
&lt;li&gt;We write .proto files. the proto compiler generates stub files which can be used to write the server as well as the client. The key takeaway here is we can use the same proto files to generate clients and servers in many different languages.&lt;/li&gt;
&lt;li&gt;Protocol Buffers are agnostic to the language you are working with to develop your server or the client. .proto files have their syntax and data types which convert to specific data types in a destination programming language. This is my favorite reason to use gRPC in my projects.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I recommend you to read through the proto syntax, keywords, and data types here: &lt;a href="https://developers.google.com/protocol-buffers/docs/proto3"&gt;https://developers.google.com/protocol-buffers/docs/proto3&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What is gRPC?
&lt;/h2&gt;

&lt;p&gt;Ever heard of RPC? It stands for Remote Procedure Call. It's an old way of running a remote procedure on a remote machine. Let me make it a little familiar for you. When you hit an endpoint from a frontend to a backend, you are making a remote call or a remote procedure call. &lt;/p&gt;

&lt;p&gt;SOAP and REST both are an example of RPC. You can send data in the body and hit an API on the other end. That's how it has been happening since the start.&lt;/p&gt;

&lt;p&gt;gRPC is a continuation of that SOAP and REST. gRPC brings all the advancements that their ancestors can't. With gRPC, a client application can directly call a method on a server application on a different machine as if it were a local object.&lt;/p&gt;

&lt;h3&gt;
  
  
  Types of Service Methods in gRPC
&lt;/h3&gt;

&lt;p&gt;We'll practically see what service methods are when we do hands-on with code. But right now I want to specify that in gRPC we have 4 kinds of method definitions.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--uw8lsFFw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://d2kbulfv42d43j.cloudfront.net/2022/Q2/grpc-service-method-types.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--uw8lsFFw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://d2kbulfv42d43j.cloudfront.net/2022/Q2/grpc-service-method-types.jpg" alt="Types of Service Methods" width="880" height="495"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Unary&lt;/strong&gt; - Unary is similar to a normal REST call. A client initiates a TCP connection, sends a message, waits for the server to respond, and finally, the server responds.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Server Streaming&lt;/strong&gt; - Server streaming RPCs where the client sends a request to the server and gets a stream to read a sequence of messages back. For example, you searched for a keyword. Instead of returning a static page, Twitter returns a stream of tweets, including whatever is being tweeted in real time.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Client Streaming&lt;/strong&gt; - Client streaming RPCs where the client writes a sequence of messages and sends them to the server. Once the client has finished writing the messages, it waits for the server to read them and return its response. Again gRPC guarantees message ordering within an individual RPC call. An example of it would be an IoT device (e.g. a car) streaming its device location to the central server (e.g. Uber).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Bidirectional Streaming&lt;/strong&gt; - Bidirectional streaming RPCs where both sides send a sequence of messages using a read-write stream. The two streams operate independently, so clients and servers can read and write in whatever order they like. An example of this would be a chat application. But I know there are more complex use cases available in the wild. Please let me know in the comments if you do so.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;For a detailed explanation of what happens when a gRPC client calls a gRPC server method, please consider reading &lt;strong&gt;&lt;a href="https://grpc.io/docs/what-is-grpc/core-concepts/#rpc-life-cycle"&gt;RPC life cycle&lt;/a&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Developing with gRPC
&lt;/h2&gt;

&lt;p&gt;We have had enough of theories. Let's develop some code to see this thing in action.&lt;/p&gt;

&lt;p&gt;We are going to have an example in Go. Although as we already know, the proto files have a language of their own which is used to generate code in multiple languages.&lt;/p&gt;

&lt;p&gt;We are going to write a simple calculator app.&lt;/p&gt;

&lt;h3&gt;
  
  
  Write the proto file
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;.proto&lt;/code&gt; files are contracts between the server and the client. This is similar to the REST API you have already experienced with.&lt;/p&gt;

&lt;p&gt;Before I proceed further, I'd like to inform you that having the whole code into a module will make your life easy. That's the reason, I've created a go module at the root of the directory named &lt;code&gt;github.com/santosh/example&lt;/code&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  calculator/calculator.proto
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight protobuf"&gt;&lt;code&gt;&lt;span class="na"&gt;syntax&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"proto3"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;option&lt;/span&gt; &lt;span class="na"&gt;go_package&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"github.com/santosh/example/calculator"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;package&lt;/span&gt; &lt;span class="nn"&gt;calculator&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// The calculator service definition.&lt;/span&gt;
&lt;span class="kd"&gt;service&lt;/span&gt; &lt;span class="n"&gt;Calculator&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Adds two number&lt;/span&gt;
    &lt;span class="k"&gt;rpc&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;Input&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;returns&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Output&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Input message containing two operands&lt;/span&gt;
&lt;span class="kd"&gt;message&lt;/span&gt; &lt;span class="nc"&gt;Input&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;int32&lt;/span&gt; &lt;span class="na"&gt;Operand1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kt"&gt;int32&lt;/span&gt; &lt;span class="na"&gt;Operand2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Output message containing result of operation&lt;/span&gt;
&lt;span class="kd"&gt;message&lt;/span&gt; &lt;span class="nc"&gt;Output&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;int32&lt;/span&gt; &lt;span class="na"&gt;Result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&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;h3&gt;
  
  
  Explanation
&lt;/h3&gt;

&lt;p&gt;Protocol buffer data is structured as messages, where each message is a small logical record of information containing a series of name-value pairs called fields. Line 7-10 is an example of a message. So is 12-14. Messages are comprised of data types, identifiers, and index positions.&lt;/p&gt;

&lt;p&gt;You'd also note messages are composed inside Services. Service is simply what this web service does. We currently have a &lt;code&gt;Calculator&lt;/code&gt; service from lines 3-5. Calculator service comprises of a method called &lt;code&gt;Add&lt;/code&gt;. Add takes 2 parameters as defined in &lt;strong&gt;Input&lt;/strong&gt; message and emits an &lt;strong&gt;Output&lt;/strong&gt; message.&lt;/p&gt;

&lt;h3&gt;
  
  
  Generate code from a proto file
&lt;/h3&gt;

&lt;p&gt;You'd need a &lt;code&gt;protoc&lt;/code&gt; compiler to generate code from proto files. If you are on Debian based system, you can use &lt;code&gt;sudo apt install protobuf-compiler&lt;/code&gt;. If you are on any other OS, please read &lt;a href="https://grpc.io/docs/protoc-installation/"&gt;Protocol Buffer Compiler Installation&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I am going to use Go for this tutorial, so I'm going to install the Go plugin for the protoc compiler.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.28
go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@v1.2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now with everything in place, I'd issue this command from the root of the module:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;protoc --go_out=. --go_opt=paths=source_relative --go-grpc_out=. --go-grpc_opt=paths=source_relative calculator/calculator.proto
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;If this command is successful, this would generate 2 more go files.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ tree calculator
calculator
├── calculator_grpc.pb.go
├── calculator.pb.go
└── calculator.proto

0 directories, 3 files
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If this is your first time with gRPC, and you look at the generated code now, you'd probably be lost.&lt;/p&gt;

&lt;p&gt;We are going to use both files to create our server and the client. The generated code will start to make sense.&lt;/p&gt;

&lt;h2&gt;
  
  
  Implement calculator server and the client
&lt;/h2&gt;

&lt;p&gt;We all know that the output generated by the &lt;code&gt;protoc&lt;/code&gt; compiler is a stub. We need to use that stub as a guide to implementing/writing our client and the server code. The stub work as a guideline for us.&lt;/p&gt;

&lt;p&gt;Right now, the generated code lives inside &lt;code&gt;calculator&lt;/code&gt; package in &lt;strong&gt;calculator.pb.go&lt;/strong&gt; which mostly deals with data part (i.e. &lt;code&gt;Input&lt;/code&gt;, &lt;code&gt;Output&lt;/code&gt;, &lt;code&gt;Operand1&lt;/code&gt;, &lt;code&gt;Operand2&lt;/code&gt;, their getters etc) and &lt;strong&gt;calculator_grpc.pb.go&lt;/strong&gt; which mostly deals with method implementation (i.e &lt;code&gt;Add&lt;/code&gt; in both server and client). The first thing in both server and client code is to import this package.&lt;/p&gt;

&lt;p&gt;I will keep referencing the proto file as we define our client/server code.&lt;/p&gt;

&lt;h3&gt;
  
  
  Write gRPC calculator server
&lt;/h3&gt;

&lt;p&gt;If you look into &lt;strong&gt;calculator_grpc.pb.go&lt;/strong&gt;, you'd find that there is a struct called &lt;code&gt;UnimplementedCalculatorServer&lt;/code&gt;. This struct represents our server. Now there is a reason it is named &lt;code&gt;Unimplemented&lt;/code&gt;. If you look at methods attached to this struct, you'd see a method named &lt;code&gt;Add&lt;/code&gt;. This is the same method we defined in our proto file. Here is a refresher:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Adds two number
rpc Add(Input) returns (Output);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;What we are going to do is we are going to take this &lt;code&gt;UnimplementedCalculatorServer&lt;/code&gt; and implement the &lt;code&gt;Add&lt;/code&gt; method.&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="c"&gt;// server is used to implement calculator.CalculatorServer.&lt;/span&gt;
&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;server&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;pb&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UnimplementedCalculatorServer&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;// Add implements calculator.CalculatorServer&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;s&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;server&lt;/span&gt;&lt;span class="p"&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;ctx&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;in&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;pb&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Input&lt;/span&gt;&lt;span class="p"&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;pb&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Output&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;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Received: %v %v"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;in&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetOperand1&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;in&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetOperand2&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
    &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;in&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetOperand1&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;in&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetOperand2&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;pb&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Output&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;Result&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;result&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;Pay attention to the signature of the method. We are taking &lt;code&gt;Input&lt;/code&gt; in form of &lt;code&gt;*pb.Input&lt;/code&gt; and returning &lt;code&gt;Output&lt;/code&gt; in form of &lt;code&gt;*pb.Output&lt;/code&gt;. This is very the same as we declared in the proto file.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;Add&lt;/code&gt; implementation is incomplete without Add logic. On line 26 we are using &lt;code&gt;GetOperand1&lt;/code&gt; and &lt;code&gt;GetOperand2&lt;/code&gt; which is available from the &lt;strong&gt;calculator.pb.go&lt;/strong&gt; file. At last, we use the Output struct to return the result.&lt;/p&gt;

&lt;p&gt;Implementing the method is not enough, we also need to start the gRPC server and start listening.&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;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;flag&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;lis&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;net&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Listen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"tcp"&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;Sprintf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;":%d"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;port&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;Fatalf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"failed to listen: %v"&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;s&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;grpc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewServer&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;pb&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RegisterCalculatorServer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&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;server&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;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"server listening at %v"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;lis&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Addr&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="n"&gt;s&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Serve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;lis&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="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;Fatalf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"failed to serve: %v"&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="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On line 32 I'm starting to listen to TCP connection on a given port. &lt;code&gt;grpc.NewServer()&lt;/code&gt; calls the internal library function to create a new gRPC server, this call returns a &lt;code&gt;grpc.ServiceRegistrar&lt;/code&gt; object. This object is then passed to &lt;code&gt;RegisterCalculatorServer&lt;/code&gt; along with our implemented methods.&lt;/p&gt;

&lt;p&gt;The whole code looks like this:&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;main&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;"flag"&lt;/span&gt;
    &lt;span class="s"&gt;"fmt"&lt;/span&gt;
    &lt;span class="s"&gt;"log"&lt;/span&gt;
    &lt;span class="s"&gt;"net"&lt;/span&gt;

    &lt;span class="n"&gt;pb&lt;/span&gt; &lt;span class="s"&gt;"github.com/santosh/example/calculator"&lt;/span&gt;
    &lt;span class="s"&gt;"google.golang.org/grpc"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;port&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;flag&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"port"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;50051&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"The server port"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c"&gt;// server is used to implement calculator.CalculatorServer.&lt;/span&gt;
&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;server&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;pb&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UnimplementedCalculatorServer&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;// Add implements calculator.CalculatorServer&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;s&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;server&lt;/span&gt;&lt;span class="p"&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;ctx&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;in&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;pb&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Input&lt;/span&gt;&lt;span class="p"&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;pb&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Output&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;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Received: %v %v"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;in&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetOperand1&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;in&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetOperand2&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
    &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;in&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetOperand1&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;in&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetOperand2&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;pb&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Output&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;Result&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;result&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;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;flag&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;lis&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;net&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Listen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"tcp"&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;Sprintf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;":%d"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;port&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;Fatalf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"failed to listen: %v"&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;s&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;grpc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewServer&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;pb&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RegisterCalculatorServer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&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;server&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;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"server listening at %v"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;lis&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Addr&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="n"&gt;s&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Serve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;lis&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="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;Fatalf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"failed to serve: %v"&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="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In above implementation, we have used &lt;code&gt;flag&lt;/code&gt; library to pass port from command line.&lt;/p&gt;

&lt;h3&gt;
  
  
  Write gRPC calculator client
&lt;/h3&gt;

&lt;p&gt;Like we have done with server code, we'll start by defining command line &lt;code&gt;flag&lt;/code&gt;s.&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;var&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;addr&lt;/span&gt;     &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;flag&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"addr"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"localhost:50051"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"the address to connect to"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;operand1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;flag&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"op1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"1st operand"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;operand2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;flag&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"op2"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"2nd operand"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;operand1int32&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;int32&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;operand1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;operand2int32&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;int32&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;operand2&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;Line 19-20 here are kind of a hack as flag module does not have a way to accept &lt;code&gt;int32&lt;/code&gt; which is requirement for our &lt;code&gt;Output.Result&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Next is connecting with the server part:&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="c"&gt;// Set up a connection to the server.&lt;/span&gt;
    &lt;span class="n"&gt;conn&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;grpc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Dial&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;addr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;grpc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WithTransportCredentials&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;insecure&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewCredentials&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;Fatalf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"did not connect: %v"&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;defer&lt;/span&gt; &lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Close&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;grpc.Dial&lt;/code&gt; takes address of the server as well as other variadic parameters. As gRPC works over HTTP2 which is by default requires TLS, we are using insecure credentials as we have not configured our server to use certificates.&lt;/p&gt;

&lt;p&gt;On the next line, we are going to create a new gRPC client:&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;c&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;pb&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewCalculatorClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On preceding lines, we are going to invoke the &lt;code&gt;Add&lt;/code&gt; endpoint:&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="c"&gt;// Contact the server and print out its response.&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;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;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Second&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="n"&gt;r&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;c&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;ctx&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;pb&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Input&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;Operand1&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;operand1int32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Operand2&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;operand2int32&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;Fatalf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"could not add: %v"&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;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Add result: %v"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetResult&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The entirity of the code looks like this:&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;main&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;"flag"&lt;/span&gt;
    &lt;span class="s"&gt;"log"&lt;/span&gt;
    &lt;span class="s"&gt;"time"&lt;/span&gt;

    &lt;span class="n"&gt;pb&lt;/span&gt; &lt;span class="s"&gt;"github.com/santosh/example/calculator"&lt;/span&gt;
    &lt;span class="s"&gt;"google.golang.org/grpc"&lt;/span&gt;
    &lt;span class="s"&gt;"google.golang.org/grpc/credentials/insecure"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;addr&lt;/span&gt;     &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;flag&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"addr"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"localhost:50051"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"the address to connect to"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;operand1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;flag&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"op1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"1st operand"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;operand2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;flag&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"op2"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"2nd operand"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;operand1int32&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;int32&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;operand1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;operand2int32&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;int32&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;operand2&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="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;flag&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="c"&gt;// Set up a connection to the server.&lt;/span&gt;
    &lt;span class="n"&gt;conn&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;grpc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Dial&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;addr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;grpc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WithTransportCredentials&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;insecure&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewCredentials&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;Fatalf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"did not connect: %v"&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;defer&lt;/span&gt; &lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Close&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;pb&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewCalculatorClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c"&gt;// Contact the server and print out its response.&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;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;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Second&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="n"&gt;r&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;c&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;ctx&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;pb&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Input&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;Operand1&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;operand1int32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Operand2&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;operand2int32&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;Fatalf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"could not add: %v"&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;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Add result: %v"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetResult&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 ahead and test our service.&lt;/p&gt;

&lt;h2&gt;
  
  
  Demo our server and the client
&lt;/h2&gt;

&lt;p&gt;I have recorded a gif for the demo.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--92pRtKE0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://d2kbulfv42d43j.cloudfront.net/2022/Q2/grpc_calculator.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--92pRtKE0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://d2kbulfv42d43j.cloudfront.net/2022/Q2/grpc_calculator.gif" alt="gRPC calculator demo" width="880" height="417"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here I have demonstrated with the default flag value, but you can override &lt;code&gt;-op1&lt;/code&gt; and &lt;code&gt;-op2&lt;/code&gt; flag to see different results.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;This was merely an introduction to gRPC and protocol buffer. What I've found is different than a conventional REST API is the endpoints. In REST, we have a predefined endpoint to hit. Such as &lt;code&gt;/calculation/add&lt;/code&gt;. We would then pass JSON with the first and the second operand.&lt;/p&gt;

&lt;p&gt;This is not the case with gRPC. We get the stub files as the &lt;code&gt;protoc&lt;/code&gt; artifact. The only communication is from there.&lt;/p&gt;

&lt;p&gt;In this post, I have only covered the &lt;strong&gt;Unary&lt;/strong&gt; service method types. I'll leave streaming for some other time. If you'd like to read and practice more gRPC, I'd found &lt;a href="https://dev.to/techschoolguru/series/7311"&gt;this series very helpful&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  External Links
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://developers.google.com/protocol-buffers/docs/proto3"&gt;Protocol Buffers Proto3 documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://grpc.io/"&gt;GRPC official Documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://stackoverflow.com/q/36517829/939986"&gt;What does multiplexing mean in HTTP/2&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>grpc</category>
      <category>http2</category>
      <category>protobuf</category>
    </item>
    <item>
      <title>Building a Book Store API in Golang With Gin</title>
      <dc:creator>Santosh Kumar</dc:creator>
      <pubDate>Fri, 18 Mar 2022 04:16:18 +0000</pubDate>
      <link>https://forem.com/santosh/building-a-book-store-api-in-golang-with-gin-4dmp</link>
      <guid>https://forem.com/santosh/building-a-book-store-api-in-golang-with-gin-4dmp</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Go community believes that we need no framework to develop web services. And I agree with that. When you work without using any framework, you learn the ins and outs of development. But once you learn how things work, you must reside in a community and don't reinvent the wheel. &lt;/p&gt;

&lt;p&gt;I have created POCs in Go before and I had to deal with HTTP headers, serializing/deserializing, error handling, database connections, and whatnot. But now I've decided to join the Gin community as it is one of the widely accepted in the software development community.&lt;/p&gt;

&lt;p&gt;Although I'm writing this post as a standalone article and would keep things simple here. But I want to continue building on these examples to have authentication, authorization, databases (including Postgres, ORM), swagger, and GraphQL covered. Will be interlinking the posts when I create them.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Gin
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fd2kbulfv42d43j.cloudfront.net%2F2022%2FQ1%2Fgin-golang-banner.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fd2kbulfv42d43j.cloudfront.net%2F2022%2FQ1%2Fgin-golang-banner.jpg"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There are numerous reasons you may want to use Gin. If you ask me, I'm a big fan of Gin's sensible defaults.&lt;/p&gt;

&lt;p&gt;Another thing I like about Gin is that it's an entire framework. You don't need a separate multiplexer and a separate middleware library and so on. On top of that, there are many common things already available that you don't have to reinvent. It does enhance our productivity. Although I'm not using it in production, I already have started to feel it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Hello World in Gin
&lt;/h2&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;main&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;"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;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;router&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;New&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="n"&gt;router&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;"/ping"&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;ctx&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;ctx&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;StatusOK&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;H&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="s"&gt;"message"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"pong"&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;router&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="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's get familiar with Gin a little bit.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;router := gin.New()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This creates an instance of  &lt;code&gt;Engine&lt;/code&gt;. &lt;code&gt;gin.Engine&lt;/code&gt; is the core of gin. It also acts as a router and that is why we have put that Engine instance into a variable called &lt;code&gt;router&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;router.GET("/ping", func(ctx *gin.Context) {
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This binds a route &lt;code&gt;/ping&lt;/code&gt; to a handler. In the example above, I've created an anonymous function, but it could be a separate function as well. The thing to note here is the parameter to this function. &lt;code&gt;*gin.Context&lt;/code&gt;. &lt;code&gt;Context&lt;/code&gt; is yet another important construct besides Engine. &lt;code&gt;Context&lt;/code&gt; has almost 100 methods attached to it. A newcomer should be spending most of their time understanding this &lt;code&gt;Context&lt;/code&gt; struct and their methods. &lt;/p&gt;

&lt;p&gt;Let's now look at the next few lines:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;        ctx.JSON(http.StatusFound, gin.H{
            "message": "pong",
        })
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;One of the &lt;code&gt;*gin.Context&lt;/code&gt; method is &lt;code&gt;JSON&lt;/code&gt;. This method is used to send a JSON response to the client. Meaning that it automatically sets response's &lt;code&gt;Content-Type&lt;/code&gt; to &lt;code&gt;application/json&lt;/code&gt;. JSON method takes an HTTP status code and a map of response. &lt;code&gt;gin.H&lt;/code&gt; is an alias to &lt;code&gt;map[string]interface{}&lt;/code&gt;. So basically we can create an object which can have string key and whatever value we want.&lt;/p&gt;

&lt;p&gt;Next is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;router.Run()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Engine.Run simply takes our router along with the route handler and binds it to http.Server. The default port is &lt;code&gt;8080&lt;/code&gt;, but if you want, you can have another address passed here. &lt;/p&gt;

&lt;h2&gt;
  
  
  The Book Store API
&lt;/h2&gt;

&lt;p&gt;I've already done a POC on bookstore before, at that time, I wanted to prototype a connection between MongoDB and Go. But this time my goal is to have Postgres and GraphQL incorporated.&lt;/p&gt;

&lt;p&gt;So first of all, I'd like you to set up a directory structure like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ tree
.
├── db
│   └── db.go
├── go.mod
├── go.sum
├── handlers
│   └── books.go
├── main.go
└── models
    └── book.go
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And let's start filling up those files. &lt;/p&gt;

&lt;h3&gt;
  
  
  db/db.go
&lt;/h3&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;db&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="s"&gt;"github.com/santosh/gingo/models"&lt;/span&gt;

&lt;span class="c"&gt;// Books slice to seed book data.&lt;/span&gt;
&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;Books&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Book&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;ISBN&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"9781612680194"&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;"Rich Dad Poor Dad"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Author&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Robert Kiyosaki"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;ISBN&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"9781781257654"&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;"The Daily Stotic"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Author&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Ryan Holiday"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;ISBN&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"9780593419052"&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;"A Mind for Numbers"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Author&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Barbara Oklay"&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;Instead of going into the complexity of setting up a database right now, I've decided to use an in-memory database for this post. In this file, I've seeded &lt;code&gt;db.Books&lt;/code&gt; slice with some books.&lt;/p&gt;

&lt;p&gt;If &lt;code&gt;models.Book&lt;/code&gt; makes, you curious, the next file is that only.&lt;/p&gt;

&lt;h3&gt;
  
  
  models/book.go
&lt;/h3&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;models&lt;/span&gt;

&lt;span class="c"&gt;// Book represents data about a book.&lt;/span&gt;
&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;Book&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;ISBN&lt;/span&gt;   &lt;span class="kt"&gt;string&lt;/span&gt;  &lt;span class="s"&gt;`json:"isbn"`&lt;/span&gt;
    &lt;span class="n"&gt;Title&lt;/span&gt;  &lt;span class="kt"&gt;string&lt;/span&gt;  &lt;span class="s"&gt;`json:"title"`&lt;/span&gt;
    &lt;span class="n"&gt;Author&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;  &lt;span class="s"&gt;`json:"author"`&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Nothing fancy here, we only have 3 fields as of now. All of them are strings and with struct tags.&lt;/p&gt;

&lt;p&gt;Let us see our main.go before we go onto handlers.go.&lt;/p&gt;

&lt;h3&gt;
  
  
  main.go
&lt;/h3&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;main&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/gin-gonic/gin"&lt;/span&gt;
    &lt;span class="s"&gt;"github.com/santosh/gingo/handlers"&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;setupRouter&lt;/span&gt;&lt;span class="p"&gt;()&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;Engine&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;router&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;Default&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;router&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;"/books"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;handlers&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetBooks&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;router&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;"/books/:isbn"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;handlers&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetBookByISBN&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="c"&gt;// router.DELETE("/books/:isbn", handlers.DeleteBookByISBN)&lt;/span&gt;
    &lt;span class="c"&gt;// router.PUT("/books/:isbn", handlers.UpdateBookByISBN)&lt;/span&gt;
    &lt;span class="n"&gt;router&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;POST&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/books"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;handlers&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PostBook&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;router&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;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;router&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;setupRouter&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;router&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;":8080"&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;Almost similar to the hello world example we saw above. But this time we have &lt;code&gt;gin.Default()&lt;/code&gt; instead of &lt;code&gt;gin.New()&lt;/code&gt;. The &lt;code&gt;Default&lt;/code&gt; comes with defaults which most of us would like to have. Like logging middleware.&lt;/p&gt;

&lt;p&gt;Frankly speaking, I haven't used much of Gin's middleware yet. But it's damn simple to create your middlewares. I'll put some links at the bottom of the post for your exploration. But for now, let's look at our handlers.&lt;/p&gt;

&lt;h3&gt;
  
  
  handlers/books.go
&lt;/h3&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;handlers&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;"github.com/gin-gonic/gin"&lt;/span&gt;
    &lt;span class="s"&gt;"github.com/santosh/gingo/db"&lt;/span&gt;
    &lt;span class="s"&gt;"github.com/santosh/gingo/models"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c"&gt;// GetBooks responds with the list of all books as JSON.&lt;/span&gt;
&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;GetBooks&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;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;StatusOK&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Books&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;// PostBook takes a book JSON and store in DB.&lt;/span&gt;
&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;PostBook&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="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;newBook&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Book&lt;/span&gt;

    &lt;span class="c"&gt;// Call BindJSON to bind the received JSON to&lt;/span&gt;
    &lt;span class="c"&gt;// newBook.&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="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;BindJSON&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;newBook&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="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="p"&gt;}&lt;/span&gt;

    &lt;span class="c"&gt;// Add the new book to the slice.&lt;/span&gt;
    &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Books&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;db&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Books&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;newBook&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;StatusCreated&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;newBook&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;// GetBookByISBN locates the book whose ISBN value matches the isbn&lt;/span&gt;
&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;GetBookByISBN&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;isbn&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;Param&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"isbn"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c"&gt;// Loop over the list of books, look for&lt;/span&gt;
    &lt;span class="c"&gt;// an book whose ISBN value matches the parameter.&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="k"&gt;range&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Books&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;a&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ISBN&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;isbn&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;StatusOK&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;a&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="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;StatusNotFound&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;H&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;"message"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"book not found"&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;// func DeleteBookByISBN(c *gin.Context) {}&lt;/span&gt;

&lt;span class="c"&gt;// func UpdateBookByISBN(c *gin.Context) {}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The real juice is in this handlers file. This might need some explanation.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;handlers.GetBooks&lt;/code&gt;, which is bound to &lt;code&gt;GET /books&lt;/code&gt; dumps the entire book slice.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;handlers.GetBookByISBN&lt;/code&gt;, which is bound to &lt;code&gt;GET /books/:isbn&lt;/code&gt; does the same thing, but it also accepts &lt;code&gt;isbn&lt;/code&gt; as a URL parameter. This handler scans the entire slice and returns the matched book. Scanning a large slice would not be the most optimal solution, but don't forget that we'll be implementing a real database while we continue to develop this bookstore.&lt;/p&gt;

&lt;p&gt;The most interesting one here is &lt;code&gt;handlers.PostBook&lt;/code&gt;, which is bound to &lt;code&gt;POST /books&lt;/code&gt;. &lt;code&gt;c.BindJSON&lt;/code&gt; is the magic method, which takes in the JSON from the request and stores it into previously created &lt;code&gt;newBook&lt;/code&gt; struct. Later on&lt;/p&gt;

&lt;h2&gt;
  
  
  Tests
&lt;/h2&gt;

&lt;p&gt;We need a little change here at the moment. We need to remove these contents from main.go:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;&lt;span class="p"&gt;@@ -1,17 +1,9 @@&lt;/span&gt;
 package main
&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="gd"&gt;-import (
-       "github.com/gin-gonic/gin"
-       "github.com/santosh/gingo/handlers"
-)
&lt;/span&gt;&lt;span class="gi"&gt;+import "github.com/santosh/gingo/routes"
&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt; func main() {
&lt;span class="gd"&gt;-       router := gin.Default()
-       router.GET("/books", handlers.GetBooks)
-       router.GET("/books/:isbn", handlers.GetBookByISBN)
-       // router.DELETE("/books/:isbn", handlers.DeleteBookByISBN)
-       // router.PUT("/books/:isbn", handlers.UpdateBookByISBN)
-       router.POST("/books", handlers.PostBook)
&lt;/span&gt;&lt;span class="gi"&gt;+       router := routes.SetupRouter()
&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;        router.Run(":8080")
 }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And put it into a new file. &lt;/p&gt;

&lt;h4&gt;
  
  
  routes/roures.go
&lt;/h4&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;routes&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/gin-gonic/gin"&lt;/span&gt;
    &lt;span class="s"&gt;"github.com/santosh/gingo/handlers"&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;SetupRouter&lt;/span&gt;&lt;span class="p"&gt;()&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;Engine&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;router&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;Default&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;router&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;"/books"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;handlers&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetBooks&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;router&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;"/books/:isbn"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;handlers&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetBookByISBN&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="c"&gt;// router.DELETE("/books/:isbn", handlers.DeleteBookByISBN)&lt;/span&gt;
    &lt;span class="c"&gt;// router.PUT("/books/:isbn", handlers.UpdateBookByISBN)&lt;/span&gt;
    &lt;span class="n"&gt;router&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;POST&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/books"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;handlers&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PostBook&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;router&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I have changes that make sense to you. We did this because we need to start the server from our tests.&lt;/p&gt;

&lt;p&gt;Next, we create a &lt;code&gt;books_test.go&lt;/code&gt; in handlers.&lt;/p&gt;

&lt;h4&gt;
  
  
  handlers/books_test.go
&lt;/h4&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;handlers_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;"bytes"&lt;/span&gt;
    &lt;span class="s"&gt;"encoding/json"&lt;/span&gt;
    &lt;span class="s"&gt;"net/http"&lt;/span&gt;
    &lt;span class="s"&gt;"net/http/httptest"&lt;/span&gt;
    &lt;span class="s"&gt;"testing"&lt;/span&gt;

    &lt;span class="s"&gt;"github.com/santosh/gingo/models"&lt;/span&gt;
    &lt;span class="s"&gt;"github.com/santosh/gingo/routes"&lt;/span&gt;
    &lt;span class="s"&gt;"github.com/stretchr/testify/assert"&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;TestBooksRoute&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;router&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;routes&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SetupRouter&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="n"&gt;w&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;httptest&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewRecorder&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&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;NewRequest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"GET"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"/books"&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;router&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ServeHTTP&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;req&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;Equal&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="m"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Code&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;Contains&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;w&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Body&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="s"&gt;"9781612680194"&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;Contains&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;w&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Body&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="s"&gt;"9781781257654"&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;Contains&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;w&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Body&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="s"&gt;"9780593419052"&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="n"&gt;TestBooksbyISBNRoute&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;router&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;routes&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SetupRouter&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="n"&gt;w&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;httptest&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewRecorder&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&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;NewRequest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"GET"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"/books/9781612680194"&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;router&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ServeHTTP&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;req&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;Equal&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="m"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Code&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;Contains&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;w&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Body&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="s"&gt;"Rich Dad Poor Dad"&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="n"&gt;TestPostBookRoute&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;router&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;routes&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SetupRouter&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="n"&gt;book&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Book&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;ISBN&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"1234567891012"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;Author&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Santosh Kumar"&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;"Hello World"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Marshal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;book&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;w&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;httptest&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewRecorder&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&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;NewRequest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"POST"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"/books"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;bytes&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewReader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="n"&gt;router&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ServeHTTP&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;req&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;Equal&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="m"&gt;201&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Code&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;Contains&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;w&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Body&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="s"&gt;"Hello World"&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;Also, again, pretty much self-explanatory. I don't think the above code needs any explanation. We are testing for response codes and response bodies for a specific string.&lt;/p&gt;

&lt;p&gt;Let's also run the tests and check how it goes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ go test ./... -cover
?       github.com/santosh/gingo        [no test files]
?       github.com/santosh/gingo/db     [no test files]
ok      github.com/santosh/gingo/handlers       (cached)        coverage: 83.3% of statements
?       github.com/santosh/gingo/models [no test files]
?       github.com/santosh/gingo/routes [no test files]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Exercise
&lt;/h2&gt;

&lt;p&gt;Yeah, let's this blog post more interesting by adding some interactivity. I have some tasks for you, which you need to solve on your own. Please have a try on them. They are:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Implement &lt;code&gt;DeleteBookByISBN&lt;/code&gt; and &lt;code&gt;UpdateBookByISBN&lt;/code&gt; handlers and enable them.&lt;/li&gt;
&lt;li&gt;Write tests for handlers mentioned above.&lt;/li&gt;
&lt;li&gt;Our tests are very basic. So are our handlers. We are not doing any error handling. Add error handling to handlers and write tests to validate them.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;We have seen how simple is it to create a hello world application in Gin. But this journey does not end here. I'll come back with more tutorials next time. Until then, goodbye.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Related Link&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://sosedoff.com/2014/12/21/gin-middleware.html" rel="noopener noreferrer"&gt;https://sosedoff.com/2014/12/21/gin-middleware.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://santoshk.dev/posts/2020/sending-post-request-in-go-with-a-body/" rel="noopener noreferrer"&gt;https://santoshk.dev/posts/2020/sending-post-request-in-go-with-a-body/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>go</category>
      <category>gin</category>
      <category>api</category>
    </item>
    <item>
      <title>__init__ vs __new__ and When to Use Them</title>
      <dc:creator>Santosh Kumar</dc:creator>
      <pubDate>Sun, 06 Mar 2022 13:18:08 +0000</pubDate>
      <link>https://forem.com/santosh/init-vs-new-and-when-to-use-them-42ei</link>
      <guid>https://forem.com/santosh/init-vs-new-and-when-to-use-them-42ei</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;I recently got asked to me what did &lt;code&gt;__init__&lt;/code&gt; dunder method did in Python. And I was like, "it is used to initialize variables inside a class". And just after that, the follow-up question was, "then what is &lt;code&gt;__new__&lt;/code&gt; used for. And I was completely blank and was not able to answer that.&lt;/p&gt;

&lt;p&gt;I was not able to answer that question because there are not many tutorials out there that talk about &lt;code&gt;__new__&lt;/code&gt;. I didn't want to happen this with you. And that is why I came up with this blog post for you.&lt;/p&gt;

&lt;h2&gt;
  
  
  Similarities
&lt;/h2&gt;

&lt;p&gt;Let's start with similarities.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Both of them are called/invoked during the creation of the instance.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Differences
&lt;/h2&gt;

&lt;p&gt;Let's start with differences.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;new&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;init&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;Called before &lt;strong&gt;init&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;Called after &lt;strong&gt;new&lt;/strong&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;Accepts a type as the first argument&lt;/td&gt;
&lt;td&gt;Accepts an instance as the first argument&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;Is supposed to return an instance of the type received&lt;/td&gt;
&lt;td&gt;Is not supposed to return anything&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;Used to control instance creation&lt;/td&gt;
&lt;td&gt;Used to initialize instance variables&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Talking about the first point. &lt;code&gt;__new__&lt;/code&gt; is called when the instance is first created. This happens before the initialization of the class. &lt;/p&gt;

&lt;p&gt;By the way, did you note that the first argument to &lt;code&gt;__init__&lt;/code&gt; is always &lt;code&gt;self&lt;/code&gt;? This self is the instance of the class. &lt;code&gt;self&lt;/code&gt; is what &lt;code&gt;__new__&lt;/code&gt; returns.&lt;/p&gt;

&lt;p&gt;Coming to the third point, &lt;code&gt;__new__&lt;/code&gt; is supposed to return an instance of the class. Note that if &lt;code&gt;__new__&lt;/code&gt; does not returns anything, &lt;code&gt;__init__&lt;/code&gt; is not called.&lt;/p&gt;

&lt;h2&gt;
  
  
  Which one of them is a constructor?
&lt;/h2&gt;

&lt;p&gt;If you are coming from another language, you might be surprised that there are two similar things doing the same kind of work. Most languages you might have worked with would have something called a constructor. &lt;/p&gt;

&lt;p&gt;In Python, that concept is broken down into &lt;strong&gt;constructor&lt;/strong&gt; and &lt;strong&gt;initializer&lt;/strong&gt;. And you might have guessed, &lt;code&gt;__new__&lt;/code&gt; is the constructor and &lt;code&gt;__init__&lt;/code&gt; is the initializer.&lt;/p&gt;

&lt;p&gt;Please note that &lt;code&gt;__new__&lt;/code&gt; is implicit. Meaning that if you don't actually need to modify the creation of an instance of the class, you don't need to have a &lt;code&gt;new&lt;/code&gt; method.&lt;/p&gt;

&lt;p&gt;One more thing I'd like to add is... instance variables are local to an instance. So anything you are doing in init is local to that instance only. But anything you are doing in new will be affecting anything created for that type.&lt;/p&gt;

&lt;h2&gt;
  
  
  Execution flow with an example
&lt;/h2&gt;

&lt;p&gt;I am going to add some code to make this more engaging. Consider this example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Demo&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__new__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cls&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"__new__ called"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;__new__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cls&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"__init__ called"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;d&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Demo&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 the simplest example of both &lt;code&gt;__new__&lt;/code&gt; and &lt;code&gt;__init__&lt;/code&gt; in action. If you save the above code in a file and run it, you'd see something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ python3 in_it.py 
__new__ called
__init__ called
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see, the new method is called first and then execution is passed to the init method.&lt;/p&gt;

&lt;h2&gt;
  
  
  Use Cases
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Use case for &lt;code&gt;__new__&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;One of the best use cases I can take an example of is when creating a Singleton. As we know, Singleton ensures a class only has one instance and provides a global point of access to it.&lt;/p&gt;

&lt;p&gt;Some of the places I have seen singleton in action are in game programming where there is only one instance of the player. Another place, if you have used frontend libraries like Vuex (or Redux), there is only one global instance of the store. Doesn't matter how many instances you create, you'll end up having only one.&lt;/p&gt;

&lt;p&gt;Let's see how to achieve similar behavior in Python:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Singleton&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;__instance&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__new__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cls&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;cls&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;__instance&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"creating..."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="n"&gt;cls&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;__instance&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;__new__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cls&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;cls&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;__instance&lt;/span&gt;

&lt;span class="n"&gt;s1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Singleton&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;s2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Singleton&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ python3 singleton.py 
creating...
&amp;lt;__main__.Singleton object at 0x7f943301d350&amp;gt;
&amp;lt;__main__.Singleton object at 0x7f943301d350&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see, &lt;strong&gt;creating...&lt;/strong&gt; is printed only once. they both point to the same memory location. In my case, it's &lt;code&gt;0x7f943301d350&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;You might be guessing that can't we do the same thing with &lt;code&gt;__init__&lt;/code&gt;? No! That's because &lt;code&gt;__init__&lt;/code&gt; does not return anything. We'll see in the next section what &lt;code&gt;__init__&lt;/code&gt; is well suited for.&lt;/p&gt;

&lt;p&gt;But first, I wanted to show you another use case of new.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Animal&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__new__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cls&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;legs&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;legs&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;2&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;Biped&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="k"&gt;else&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;Quadruped&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Biped&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Initializing 2-legged animal"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Quadruped&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Initializing 4-legged animal"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;anim1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Animal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;legs&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;anim1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Animal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;legs&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ python3 newexample.py 
Initializing 4-legged animal
Initializing 2-legged animal
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I am by no means a zoologist. But you get my point here. You can use &lt;code&gt;__new__&lt;/code&gt; to conditionally create an instance from a class.&lt;/p&gt;

&lt;h3&gt;
  
  
  Use case for &lt;code&gt;__init__&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;As we have already seen previously. &lt;code&gt;init&lt;/code&gt; is there to initialize an instance variable. These instance variables can later be used in different methods of the instance. &lt;/p&gt;

&lt;p&gt;I have extensively used &lt;code&gt;__init__&lt;/code&gt; when I used to work with &lt;a href="https://www.qt.io/"&gt;Qt framework&lt;/a&gt;. Qt is a framework for desktop-based UI development. When initializing UI objects, you can set how wide or long the window could be. You can also read preferences from a file and apply that during the initialization phase of an application. Setting the window title could be another example.&lt;/p&gt;

&lt;p&gt;Here I'll demonstrate one such example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Window&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;QWidget&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
   &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;parent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
      &lt;span class="nb"&gt;super&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Window&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;parent&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;resize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;setWindowTitle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"My App"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The above example is by no means a complete example, but when set up correctly, it will show a window similar to this. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--pOboZ5p9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://d2kbulfv42d43j.cloudfront.net/2022/Q1/example_python_qt_application.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--pOboZ5p9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://d2kbulfv42d43j.cloudfront.net/2022/Q1/example_python_qt_application.png" alt="Sample PySide window" width="222" height="177"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Key Takeaways
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;In most cases, you don't need &lt;/li&gt;
&lt;li&gt;
&lt;code&gt;__new__&lt;/code&gt; is called before &lt;code&gt;__init__&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;__new__&lt;/code&gt; returns a instance of class. &lt;/li&gt;
&lt;li&gt;
&lt;code&gt;__init__&lt;/code&gt; receives the instances of the class returned by &lt;code&gt;__new__&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;__init__&lt;/code&gt; to initilize value.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The same concept can be used to answer the question of abstraction vs encapsulation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;That is all I know about &lt;code&gt;__init__&lt;/code&gt; vs &lt;code&gt;__new__&lt;/code&gt;. If you have something in your mind that I missed. Please let me know.&lt;/p&gt;

&lt;p&gt;I'll also list some references I look to write this blog post so that you can really the real source of information.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://dev.to/pila/constructors-in-python-init-vs-new-2f9j"&gt;https://dev.to/pila/constructors-in-python-init-vs-new-2f9j&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.reddit.com/r/learnpython/comments/2s3pms/what_is_the_difference_between_init_and_new/"&gt;https://www.reddit.com/r/learnpython/comments/2s3pms/what_is_the_difference_between_init_and_new/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.pythonprogramming.in/how-to-use-new-and-init-in-python.html"&gt;https://www.pythonprogramming.in/how-to-use-new-and-init-in-python.html&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>python</category>
    </item>
  </channel>
</rss>
