<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Heertheeswaran V</title>
    <description>The latest articles on DEV Community by Heertheeswaran V (@heerthees).</description>
    <link>https://dev.to/heerthees</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%2F234339%2F242f5a8f-3a73-4220-a60a-731e99a37dd2.jpg</url>
      <title>DEV Community: Heertheeswaran V</title>
      <link>https://dev.to/heerthees</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/heerthees"/>
    <language>en</language>
    <item>
      <title>SOLVED - SameSite Issue With Rails in Chrome</title>
      <dc:creator>Heertheeswaran V</dc:creator>
      <pubDate>Wed, 30 Sep 2020 11:58:10 +0000</pubDate>
      <link>https://dev.to/heerthees/solved-samesite-issue-with-rails-in-chrome-3g26</link>
      <guid>https://dev.to/heerthees/solved-samesite-issue-with-rails-in-chrome-3g26</guid>
      <description>&lt;p&gt;&lt;strong&gt;What is SameSite?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The SameSite attribute tells the browser when and how to use the cookie with first or third party applications. SameSite is used by most of the browsers to identify whether or not to allow cookies to be accessed.&lt;/p&gt;

&lt;p&gt;The Values for SameSite attributes include&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Lax -&lt;/strong&gt; enables only the first-party cookies to be accessed.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Strict -&lt;/strong&gt; enables only the first-party cookies and also does not allow request from an external site to access the cookies.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;None -&lt;/strong&gt; enables the cookies to be accessed by third parties/external sites.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Update In Chrome:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Previously, if the SameSite attribute is not set, it was defaulted to ‘none’ - which allows the third-party to access the cookies. Now, if the SameSite attribute is not set, Chrome defaults to ‘lax’ which allows only the first party to access the cookies.&lt;/p&gt;

&lt;p&gt;So, if you need your application cookies to be accessed by a third party then we need to explicitly specify SameSite as ‘none’. In this case, we also need to specify &lt;strong&gt;Secure.&lt;/strong&gt; Only if we explicitly specify ‘&lt;strong&gt;SameSite: None; Secure&lt;/strong&gt;’, the cookies are shared to the third party.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How do we resolve this issue in Rails?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To resolve this issue in Rails, we need to explicitly set the cookies with SameSite=None and Secure. To set the SameSite and Secure we need to modify the &lt;strong&gt;session_store.rb.&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;initializers&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;session_store&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;rb&lt;/span&gt;

&lt;span class="no"&gt;Rails&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;application&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;session_store&lt;/span&gt; &lt;span class="ss"&gt;:cookie_store&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="ss"&gt;:key&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'_application_session'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="ss"&gt;:domain&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="ss"&gt;:all&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="ss"&gt;:same_site&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="ss"&gt;:none&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="ss"&gt;:secure&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="ss"&gt;:true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="ss"&gt;:tld_length&lt;/span&gt; &lt;span class="o"&gt;=&amp;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;The only catch is since we have specified the Secure attribute, the cookies will be shared only with the secured connection(HTTPS). In order to test this in your development environment, use &lt;a href="https://ngrok.com/" rel="noopener noreferrer"&gt;ngrok&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;That’s it! Your application will work perfectly in Chrome. Cheers!&lt;/p&gt;

</description>
      <category>samesite</category>
      <category>chrome</category>
      <category>cookies</category>
      <category>rails</category>
    </item>
    <item>
      <title>Custom Domain Login in Ruby on Rails</title>
      <dc:creator>Heertheeswaran V</dc:creator>
      <pubDate>Wed, 23 Sep 2020 04:58:21 +0000</pubDate>
      <link>https://dev.to/heerthees/custom-domain-login-in-ruby-on-rails-5ffo</link>
      <guid>https://dev.to/heerthees/custom-domain-login-in-ruby-on-rails-5ffo</guid>
      <description>&lt;h3&gt;
  
  
  Why Custom Domain?
&lt;/h3&gt;

&lt;p&gt;Let’s take a scenario, in which an application &lt;a href="https://app.example.org" rel="noopener noreferrer"&gt;https://app.example.org&lt;/a&gt; has to be accessed by multiple organizations (for instance, Org1 and Org2) with their own domain such as &lt;a href="https://app.org1.org" rel="noopener noreferrer"&gt;https://app.org1.org&lt;/a&gt; and &lt;a href="https://app.org2.org" rel="noopener noreferrer"&gt;https://app.org2.org&lt;/a&gt;. This can be achieved by introducing a custom domain (the domain in which the user wants to access the application) in the application.&lt;/p&gt;

&lt;p&gt;To create a system with custom domain features, you have to maintain the session in a multi-domain environment. Handling sessions in this multi-domain environment is not simple, because the cookies are mapped to the domain to where it is set.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Setting up Custom Domain Session&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Let’s take an example where the URL of the application is &lt;a href="https://app.example.org" rel="noopener noreferrer"&gt;https://app.example.org&lt;/a&gt; and it has to be accessed with &lt;a href="https://site.example1.org" rel="noopener noreferrer"&gt;https://site.example1.org&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;We will be using device authentication in this application. When we login with email and password there will be no confusion as the host is the same across all the actions. Also, the session was set by the domain accessed for the login. But, when we use omniauth logins such as Google or GitHub, there will be a difficulty as the callback URL can’t be set dynamically.&lt;/p&gt;

&lt;p&gt;To overcome this difficulty, we follow the below-mentioned steps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Set the device’s default user authentication to ‘omniauth’ authentication&lt;/li&gt;
&lt;li&gt;In the callback action, redirect the custom domain (as Host) with a unique token (to identify the user) to the custom actions&lt;/li&gt;
&lt;li&gt;In the custom action, the user is identified and logged in to the custom domain&lt;/li&gt;
&lt;li&gt;Now, the session is set by the custom domain and the user can access the entire application&lt;/li&gt;
&lt;li&gt;Here, the application (&lt;em&gt;app.example.org&lt;/em&gt;) acts as the base for many other mini-applications (&lt;em&gt;site.example1.org, etc.,&lt;/em&gt;).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let’s see the above steps in detail with google login as an example. Let’s say that the Google Auth Callback URL is &lt;em&gt;app.example.org/users/auth/google_oauth2/callback&lt;/em&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Omniauth Origin
&lt;/h3&gt;

&lt;p&gt;In Omniauth, we have a parameter in the request which gives the origin URL of the authentication process. Let’s say we have the Sign In With Google Button in the_ /user/sign_in &lt;em&gt;action. If the user clicks it from _app.example.org/user/sign_in,&lt;/em&gt; then this parameter will be the URL. This will be available in the following key &lt;b&gt;request.env['omniauth.origin']&lt;/b&gt;. With this, we can find the host/domain of the request.&lt;/p&gt;

&lt;h3&gt;
  
  
  Custom Domain Login in Practice
&lt;/h3&gt;

&lt;p&gt;When the user login with the custom domain URL &lt;a href="https://site.example1.org/user/signin" rel="noopener noreferrer"&gt;&lt;code&gt;https://site.example1.org/user/signin&lt;/code&gt;&lt;/a&gt;, the below Omniauth Callback action has to be performed:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Authenticate the user in the Application Level (across the application).&lt;/li&gt;
&lt;li&gt;Find the Host from the Omniauth Origin. In this case, the host will be &lt;strong&gt;&lt;em&gt;site.example1.org&lt;/em&gt;&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;URI.parse(request.env['omniauth.origin']).host)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Redirect to the custom action with the host as omniauth origin, along with the unique token to identify the authenticated user. Let’s call this custom action as &lt;em&gt;social_login&lt;/em&gt;. To identify the user, we will encrypt the email as the unique token (as a parameter). So the redirect URL can be generated as &lt;code&gt;"https://#{HOST}/user/social_login?key=#{user.encrypt_email}"&lt;/code&gt; and the redirect URL will be “&lt;strong&gt;&lt;a href="https://site.example1.org/user/social_login?key=encrypted_key" rel="noopener noreferrer"&gt;https://site.example1.org/user/social_login?key=encrypted_key&lt;/a&gt;&lt;/strong&gt;”.&lt;/li&gt;
&lt;li&gt;In the Social Login action, we can identify the user by decrypting the email which was received as the parameter in the above step. After identifying the user, we can sign in the user with the device &lt;strong&gt;&lt;em&gt;sign_in&lt;/em&gt;&lt;/strong&gt; function. Now, the user’s session will be tied to the custom domain.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;social_login&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"key"&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;present?&lt;/span&gt;
    &lt;span class="vi"&gt;@user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;User&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find_by&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
     &lt;span class="ss"&gt;email: &lt;/span&gt;&lt;span class="no"&gt;User&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;decrypt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"key"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="vi"&gt;@user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;present?&lt;/span&gt;
      &lt;span class="n"&gt;sign_in&lt;/span&gt; &lt;span class="vi"&gt;@user&lt;/span&gt;
      &lt;span class="n"&gt;check_private_organizaiton&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt;
      &lt;span class="n"&gt;redirect_to&lt;/span&gt; &lt;span class="n"&gt;root_path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;notice: &lt;/span&gt;&lt;span class="s2"&gt;"Please try again!"&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;else&lt;/span&gt;
    &lt;span class="n"&gt;redirect_to&lt;/span&gt; &lt;span class="n"&gt;root_path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;notice: &lt;/span&gt;&lt;span class="s2"&gt;"Please try again!"&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I hope this blog gives you an idea to maintain a session with a custom domain! Try it out and let me know what do you think at &lt;a href="//mailto:heerthees@skcript.com"&gt;heerthees@skcript.com&lt;/a&gt;&lt;/p&gt;

</description>
      <category>rails</category>
      <category>customdomain</category>
      <category>ruby</category>
      <category>authentication</category>
    </item>
    <item>
      <title>Protobuf with GO</title>
      <dc:creator>Heertheeswaran V</dc:creator>
      <pubDate>Tue, 22 Sep 2020 04:39:58 +0000</pubDate>
      <link>https://dev.to/heerthees/protobuf-with-go-4hb</link>
      <guid>https://dev.to/heerthees/protobuf-with-go-4hb</guid>
      <description>&lt;p&gt;Hey fellow coders, this is the second post of my Go series. You can check my last blog if you want to know how to set up your Go workspace. In this article, we are going to see what Protocol Buffers are, data format and how to implement it in a Go-based application.&lt;/p&gt;

&lt;p&gt;What is Protocol Buffer?&lt;/p&gt;

&lt;p&gt;Protocol Buffer is a data format, like JSON and XML which stores the structured data that can be serialized and deserialized. It is a data format developed by Google. The main advantage of Protobuf is that it is much smaller than the other formats.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Protobuf is 3 to 10 times smaller and 20 to 100 times faster than XML.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Now, let’s take a football game and represent the data in XML, JSON, and Protobuf.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;game&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;home&amp;gt;&lt;/span&gt;Real Madrid&lt;span class="nt"&gt;&amp;lt;/home&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;away&amp;gt;&lt;/span&gt;Barcelona&lt;span class="nt"&gt;&amp;lt;/away&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;venue&amp;gt;&lt;/span&gt;Santiago Bernabéu Stadium&lt;span class="nt"&gt;&amp;lt;/venue&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;date&amp;gt;&lt;/span&gt;26-10-2019&lt;span class="nt"&gt;&amp;lt;/date&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/game&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;JSON:&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;"home"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Real Madrid"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"away"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Barcelona"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"venue"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Santiago Bernabéu Stadium"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"date"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"26-10-2019"&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;Protobuf:&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="mi"&gt;10&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;11&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;82&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;101&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;97&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;108&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;32&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;77&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;97&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;114&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;105&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;18&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;66&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;97&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;114&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;99&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;101&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;108&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;111&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;110&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;97&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;26&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;26&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;83&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;97&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;110&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;116&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;105&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;97&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;103&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;111&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;32&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;66&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;101&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;114&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;110&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;97&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;98&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;195&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;169&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;117&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;32&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;83&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;116&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;97&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;105&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;117&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;109&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;34&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;54&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;45&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;49&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;48&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;45&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;48&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;49&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;57&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;The above shown protobuf format is the encoded byte of the string, starting from position 2 in the array. The string “Real Madrid” is spelled out: R = 82, e = 101 and so on.&lt;/p&gt;

&lt;p&gt;To know about this encoding, please check out Google’s own documentation here: &lt;a href="https://developers.google.com/protocol-buffers/docs/encoding" rel="noopener noreferrer"&gt;Proton Buffer Encoding&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;At this scale, the size is mostly similar. But when we scale it to larger data, the size starts to show a huge difference.&lt;/p&gt;

&lt;p&gt;So, now let’s bring Protobuf to our Go code.&lt;/p&gt;

&lt;p&gt;Installing Packages&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="err"&gt;➜&lt;/span&gt;  &lt;span class="n"&gt;go_workspace&lt;/span&gt; &lt;span class="k"&gt;go&lt;/span&gt; &lt;span class="n"&gt;get&lt;/span&gt; &lt;span class="n"&gt;github&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;com&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;golang&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;protobuf&lt;/span&gt;
&lt;span class="err"&gt;➜&lt;/span&gt;  &lt;span class="n"&gt;go_workspace&lt;/span&gt; &lt;span class="k"&gt;go&lt;/span&gt; &lt;span class="n"&gt;get&lt;/span&gt; &lt;span class="n"&gt;github&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;com&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;golang&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;protobuf&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;proto&lt;/span&gt;
&lt;span class="err"&gt;➜&lt;/span&gt;  &lt;span class="n"&gt;go_workspace&lt;/span&gt; &lt;span class="k"&gt;go&lt;/span&gt; &lt;span class="n"&gt;get&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;u&lt;/span&gt; &lt;span class="n"&gt;github&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;com&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;golang&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;protobuf&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;protoc&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;gen&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="k"&gt;go&lt;/span&gt;
&lt;span class="err"&gt;➜&lt;/span&gt;  &lt;span class="n"&gt;go_workspace&lt;/span&gt; &lt;span class="n"&gt;export&lt;/span&gt; &lt;span class="n"&gt;PATH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="n"&gt;PATH&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="n"&gt;GOPATH&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;bin&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will install the necessary packages and we are now ready.&lt;/p&gt;

&lt;p&gt;Now, let’s go and define the protobuf for the game object.&lt;/p&gt;

&lt;p&gt;Game.proto&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="err"&gt;syntax&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"proto3"&lt;/span&gt;&lt;span class="err"&gt;;&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="err"&gt;package&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;main;&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="err"&gt;message&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Game&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="err"&gt;string&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;home&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="err"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;string&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;away&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="err"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;string&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;venue&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="err"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;string&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;date&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="err"&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;We start by specifying the version syntax of proto. Here we set syntax to ‘proto3’. Next, we define the package in which this object is to be used. After that, we will define the format of our Game object. This consists of our message format of type Game which features the following fields, home, away, venue and date.&lt;/p&gt;

&lt;p&gt;As we defined the proto file, we are going to compile it with the protoc.&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="err"&gt;➜&lt;/span&gt;  &lt;span class="n"&gt;go_workspace&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;src&lt;/span&gt; &lt;span class="n"&gt;protoc&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;go_out&lt;/span&gt;&lt;span class="o"&gt;=.&lt;/span&gt; &lt;span class="o"&gt;*.&lt;/span&gt;&lt;span class="n"&gt;proto&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will generate a game.pb.go file, which has the auto-generated code. For a detailed understanding of this code, check out Google’s documentation: &lt;a href="https://developers.google.com/protocol-buffers/docs/reference/go-generated" rel="noopener noreferrer"&gt;Go generated code&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;main.go&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="n"&gt;fmt&lt;/span&gt; &lt;span class="s"&gt;"fmt"&lt;/span&gt;
  &lt;span class="s"&gt;"log"&lt;/span&gt;
  &lt;span class="n"&gt;proto&lt;/span&gt; &lt;span class="s"&gt;"github.com/golang/protobuf/proto"&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;elClasico&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;Game&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Home&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;  &lt;span class="s"&gt;"Real Madrid"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;Away&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;  &lt;span class="s"&gt;"Barcelona"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;Venue&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Santiago Bernabéu Stadium"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;Date&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;  &lt;span class="s"&gt;"26-10-2019"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="n"&gt;data&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;proto&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;elClasico&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Fatal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Marshaling error: "&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;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="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;newElClasico&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;Game&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;proto&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Unmarshal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;newElClasico&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Fatal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"UnMarshaling error: "&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;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="n"&gt;newElClasico&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetHome&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="n"&gt;newElClasico&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetAway&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="n"&gt;newElClasico&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetVenue&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="n"&gt;newElClasico&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetDate&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 the above code, we use the Game struct defined in the game.pb.go to add details to the elClasico object. We use the Marshal function of the proto library to convert the object to the Protobuf format. Then the encoded bytes can be decoded with the Unmarshal function. Now we can use the function GetHome, GetAway generated in the game.pb.go file to get the values from the decoded object.&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="err"&gt;➜&lt;/span&gt;  &lt;span class="n"&gt;go_workspace&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;src&lt;/span&gt; &lt;span class="k"&gt;go&lt;/span&gt; &lt;span class="n"&gt;run&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="k"&gt;go&lt;/span&gt; &lt;span class="n"&gt;game&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="k"&gt;go&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="m"&gt;10&lt;/span&gt; &lt;span class="m"&gt;11&lt;/span&gt; &lt;span class="m"&gt;82&lt;/span&gt; &lt;span class="m"&gt;101&lt;/span&gt; &lt;span class="m"&gt;97&lt;/span&gt; &lt;span class="m"&gt;108&lt;/span&gt; &lt;span class="m"&gt;32&lt;/span&gt; &lt;span class="m"&gt;77&lt;/span&gt; &lt;span class="m"&gt;97&lt;/span&gt; &lt;span class="m"&gt;100&lt;/span&gt; &lt;span class="m"&gt;114&lt;/span&gt; &lt;span class="m"&gt;105&lt;/span&gt; &lt;span class="m"&gt;100&lt;/span&gt; &lt;span class="m"&gt;18&lt;/span&gt; &lt;span class="m"&gt;9&lt;/span&gt; &lt;span class="m"&gt;66&lt;/span&gt; &lt;span class="m"&gt;97&lt;/span&gt; &lt;span class="m"&gt;114&lt;/span&gt; &lt;span class="m"&gt;99&lt;/span&gt; &lt;span class="m"&gt;101&lt;/span&gt; &lt;span class="m"&gt;108&lt;/span&gt; &lt;span class="m"&gt;111&lt;/span&gt; &lt;span class="m"&gt;110&lt;/span&gt; &lt;span class="m"&gt;97&lt;/span&gt; &lt;span class="m"&gt;26&lt;/span&gt; &lt;span class="m"&gt;26&lt;/span&gt; &lt;span class="m"&gt;83&lt;/span&gt; &lt;span class="m"&gt;97&lt;/span&gt; &lt;span class="m"&gt;110&lt;/span&gt; &lt;span class="m"&gt;116&lt;/span&gt; &lt;span class="m"&gt;105&lt;/span&gt; &lt;span class="m"&gt;97&lt;/span&gt; &lt;span class="m"&gt;103&lt;/span&gt; &lt;span class="m"&gt;111&lt;/span&gt; &lt;span class="m"&gt;32&lt;/span&gt; &lt;span class="m"&gt;66&lt;/span&gt; &lt;span class="m"&gt;101&lt;/span&gt; &lt;span class="m"&gt;114&lt;/span&gt; &lt;span class="m"&gt;110&lt;/span&gt; &lt;span class="m"&gt;97&lt;/span&gt; &lt;span class="m"&gt;98&lt;/span&gt; &lt;span class="m"&gt;195&lt;/span&gt; &lt;span class="m"&gt;169&lt;/span&gt; &lt;span class="m"&gt;117&lt;/span&gt; &lt;span class="m"&gt;32&lt;/span&gt; &lt;span class="m"&gt;83&lt;/span&gt; &lt;span class="m"&gt;116&lt;/span&gt; &lt;span class="m"&gt;97&lt;/span&gt; &lt;span class="m"&gt;100&lt;/span&gt; &lt;span class="m"&gt;105&lt;/span&gt; &lt;span class="m"&gt;117&lt;/span&gt; &lt;span class="m"&gt;109&lt;/span&gt; &lt;span class="m"&gt;34&lt;/span&gt; &lt;span class="m"&gt;10&lt;/span&gt; &lt;span class="m"&gt;50&lt;/span&gt; &lt;span class="m"&gt;54&lt;/span&gt; &lt;span class="m"&gt;45&lt;/span&gt; &lt;span class="m"&gt;49&lt;/span&gt; &lt;span class="m"&gt;48&lt;/span&gt; &lt;span class="m"&gt;45&lt;/span&gt; &lt;span class="m"&gt;50&lt;/span&gt; &lt;span class="m"&gt;48&lt;/span&gt; &lt;span class="m"&gt;49&lt;/span&gt; &lt;span class="m"&gt;57&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;Home&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;  &lt;span class="n"&gt;Real&lt;/span&gt; &lt;span class="n"&gt;Madrid&lt;/span&gt;
&lt;span class="n"&gt;Away&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;  &lt;span class="n"&gt;Barcelona&lt;/span&gt;
&lt;span class="n"&gt;Venue&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;  &lt;span class="n"&gt;Santiago&lt;/span&gt; &lt;span class="n"&gt;Bernabéu&lt;/span&gt; &lt;span class="n"&gt;Stadium&lt;/span&gt;
&lt;span class="n"&gt;Date&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;  &lt;span class="m"&gt;26&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="m"&gt;10&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="m"&gt;2019&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Don’t forget to include the game.pb.go. Now we have a small example up and running. But actually in the real world, the data is not going to be this simple. Now let’s see some nested fields.&lt;/p&gt;

&lt;p&gt;We will use the same Game object. In this, we are taking the fields home and away and making it an object Team.&lt;/p&gt;

&lt;p&gt;game.proto:&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;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;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="n"&gt;Team&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;home&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;away&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="n"&gt;Game&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;Team&lt;/span&gt; &lt;span class="n"&gt;team&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;venue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;date&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="m"&gt;3&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So again, we create the auto-generated code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="err"&gt;➜&lt;/span&gt;  &lt;span class="n"&gt;go_workspace&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;src&lt;/span&gt; &lt;span class="n"&gt;protoc&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;go_out&lt;/span&gt;&lt;span class="o"&gt;=.&lt;/span&gt; &lt;span class="o"&gt;*.&lt;/span&gt;&lt;span class="n"&gt;proto&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And we update the main.go file correspondingly.&lt;/p&gt;

&lt;p&gt;main.go&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="n"&gt;fmt&lt;/span&gt; &lt;span class="s"&gt;"fmt"&lt;/span&gt;
  &lt;span class="s"&gt;"log"&lt;/span&gt;
  &lt;span class="n"&gt;proto&lt;/span&gt; &lt;span class="s"&gt;"github.com/golang/protobuf/proto"&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;elClasico&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;Game&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Venue&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Santiago Bernabéu Stadium"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;Date&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;  &lt;span class="s"&gt;"26-10-2019"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;Team&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;Team&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="n"&gt;Home&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Real Madrid"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="n"&gt;Away&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Barcelona"&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;data&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;proto&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;elClasico&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Fatal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"marshaling error: "&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;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="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;newElClasico&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;Game&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;proto&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Unmarshal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;newElClasico&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Fatal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"unmarshaling error: "&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;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;"Home: "&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;newElClasico&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Team&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetHome&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;"Away: "&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;newElClasico&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Team&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetAway&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;"Venue: "&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;newElClasico&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetVenue&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;"Date: "&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;newElClasico&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetDate&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 if we run the program.&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="err"&gt;➜&lt;/span&gt;  &lt;span class="n"&gt;go_workspace&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;src&lt;/span&gt; &lt;span class="k"&gt;go&lt;/span&gt; &lt;span class="n"&gt;run&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="k"&gt;go&lt;/span&gt; &lt;span class="n"&gt;game&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="k"&gt;go&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="m"&gt;10&lt;/span&gt; &lt;span class="m"&gt;24&lt;/span&gt; &lt;span class="m"&gt;10&lt;/span&gt; &lt;span class="m"&gt;11&lt;/span&gt; &lt;span class="m"&gt;82&lt;/span&gt; &lt;span class="m"&gt;101&lt;/span&gt; &lt;span class="m"&gt;97&lt;/span&gt; &lt;span class="m"&gt;108&lt;/span&gt; &lt;span class="m"&gt;32&lt;/span&gt; &lt;span class="m"&gt;77&lt;/span&gt; &lt;span class="m"&gt;97&lt;/span&gt; &lt;span class="m"&gt;100&lt;/span&gt; &lt;span class="m"&gt;114&lt;/span&gt; &lt;span class="m"&gt;105&lt;/span&gt; &lt;span class="m"&gt;100&lt;/span&gt; &lt;span class="m"&gt;18&lt;/span&gt; &lt;span class="m"&gt;9&lt;/span&gt; &lt;span class="m"&gt;66&lt;/span&gt; &lt;span class="m"&gt;97&lt;/span&gt; &lt;span class="m"&gt;114&lt;/span&gt; &lt;span class="m"&gt;99&lt;/span&gt; &lt;span class="m"&gt;101&lt;/span&gt; &lt;span class="m"&gt;108&lt;/span&gt; &lt;span class="m"&gt;111&lt;/span&gt; &lt;span class="m"&gt;110&lt;/span&gt; &lt;span class="m"&gt;97&lt;/span&gt; &lt;span class="m"&gt;18&lt;/span&gt; &lt;span class="m"&gt;26&lt;/span&gt; &lt;span class="m"&gt;83&lt;/span&gt; &lt;span class="m"&gt;97&lt;/span&gt; &lt;span class="m"&gt;110&lt;/span&gt; &lt;span class="m"&gt;116&lt;/span&gt; &lt;span class="m"&gt;105&lt;/span&gt; &lt;span class="m"&gt;97&lt;/span&gt; &lt;span class="m"&gt;103&lt;/span&gt; &lt;span class="m"&gt;111&lt;/span&gt; &lt;span class="m"&gt;32&lt;/span&gt; &lt;span class="m"&gt;66&lt;/span&gt; &lt;span class="m"&gt;101&lt;/span&gt; &lt;span class="m"&gt;114&lt;/span&gt; &lt;span class="m"&gt;110&lt;/span&gt; &lt;span class="m"&gt;97&lt;/span&gt; &lt;span class="m"&gt;98&lt;/span&gt; &lt;span class="m"&gt;195&lt;/span&gt; &lt;span class="m"&gt;169&lt;/span&gt; &lt;span class="m"&gt;117&lt;/span&gt; &lt;span class="m"&gt;32&lt;/span&gt; &lt;span class="m"&gt;83&lt;/span&gt; &lt;span class="m"&gt;116&lt;/span&gt; &lt;span class="m"&gt;97&lt;/span&gt; &lt;span class="m"&gt;100&lt;/span&gt; &lt;span class="m"&gt;105&lt;/span&gt; &lt;span class="m"&gt;117&lt;/span&gt; &lt;span class="m"&gt;109&lt;/span&gt; &lt;span class="m"&gt;26&lt;/span&gt; &lt;span class="m"&gt;10&lt;/span&gt; &lt;span class="m"&gt;50&lt;/span&gt; &lt;span class="m"&gt;54&lt;/span&gt; &lt;span class="m"&gt;45&lt;/span&gt; &lt;span class="m"&gt;49&lt;/span&gt; &lt;span class="m"&gt;48&lt;/span&gt; &lt;span class="m"&gt;45&lt;/span&gt; &lt;span class="m"&gt;50&lt;/span&gt; &lt;span class="m"&gt;48&lt;/span&gt; &lt;span class="m"&gt;49&lt;/span&gt; &lt;span class="m"&gt;57&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;Home&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;  &lt;span class="n"&gt;Real&lt;/span&gt; &lt;span class="n"&gt;Madrid&lt;/span&gt;
&lt;span class="n"&gt;Away&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;  &lt;span class="n"&gt;Barcelona&lt;/span&gt;
&lt;span class="n"&gt;Venue&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;  &lt;span class="n"&gt;Santiago&lt;/span&gt; &lt;span class="n"&gt;Bernabéu&lt;/span&gt; &lt;span class="n"&gt;Stadium&lt;/span&gt;
&lt;span class="n"&gt;Date&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;  &lt;span class="m"&gt;26&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="m"&gt;10&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="m"&gt;2019&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Interesting, isn’t it?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3s8ybn94b32hdjdo0ffi.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3s8ybn94b32hdjdo0ffi.gif" width="1024" height="1024"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Alright guys, we now know how to use protocol buffer data format with Go. That’s it for now. Will meet you guys again with another interesting topic.&lt;/p&gt;

</description>
      <category>go</category>
      <category>protobuf</category>
    </item>
    <item>
      <title>Django for Rails Developers</title>
      <dc:creator>Heertheeswaran V</dc:creator>
      <pubDate>Sun, 20 Sep 2020 04:28:01 +0000</pubDate>
      <link>https://dev.to/heerthees/django-for-rails-developers-lmg</link>
      <guid>https://dev.to/heerthees/django-for-rails-developers-lmg</guid>
      <description>&lt;p&gt;For the past 3 years, I’ve worked on both Rails and Django. Though Rails is my favorite (Yes, Swaathi made me write this), I would like to show you how similar and sometimes strikingly different both are. This article helps any Rails dev easily port over to Django. Well, what are we waiting for, let’s get started! :D&lt;/p&gt;

&lt;h3&gt;
  
  
  Installation:
&lt;/h3&gt;

&lt;p&gt;Make sure you have Python (at least 3) installed.&lt;br&gt;
Then just do this,&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;tr&gt;
&lt;td&gt;Rails
&lt;/td&gt;
&lt;td&gt;Django
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;gem install rails&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;pip install django&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;So similar!&lt;/p&gt;
&lt;h3&gt;
  
  
  Architecture:
&lt;/h3&gt;

&lt;p&gt;Rails follows the MVC (Model, View, Controller) architecture. The Model is a representation of the database structure that is encapsulated in the host language. The Controller acts as an interface between the outside and inside world of a web framework. This is basically where requests are received and processed before responding. The View is a template that is shown to the user.&lt;/p&gt;

&lt;p&gt;Django follows MVT (Model, View, Template) architecture. Here the view acts as the Rails controller and the template acts as the Rails view - I know, confusing!&lt;/p&gt;
&lt;h3&gt;
  
  
  Create App:
&lt;/h3&gt;

&lt;p&gt;Rails uses “app” to represent the working directory. Whereas in Django, “project” is used.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;tr&gt;
&lt;td&gt;Rails
&lt;/td&gt;
&lt;td&gt;Django
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;rails new &lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;django-admin startproject &lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;&lt;/div&gt;
&lt;h3&gt;
  
  
  Run Development Server:
&lt;/h3&gt;

&lt;p&gt;Both Rails and Django come bundled with a local web server.  The default port is 8000 in Django and 3000 in Rails. The Django server is a light weight server purely written in Python where as in Rails the server is a Puma web server.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;tr&gt;
&lt;td&gt;Rails
&lt;/td&gt;
&lt;td&gt;Django
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;rails server&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;python manage.py runserver&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;&lt;/div&gt;
&lt;h3&gt;
  
  
  Settings.py:
&lt;/h3&gt;

&lt;p&gt;Settings.py is similar to application.rb where we have the configurations of the project. In Django, all the configurations like database connection, timezone, template location, allowed hosts and so on are added to settings.py.&lt;/p&gt;
&lt;h3&gt;
  
  
  Manage.py:
&lt;/h3&gt;

&lt;p&gt;Manage.py is the most important file when it comes to Django. This manage.py has the core functions required like makemigrations, migrate, runserver and so on.&lt;/p&gt;
&lt;h3&gt;
  
  
  Migrations:
&lt;/h3&gt;

&lt;p&gt;Unlike Rails the migrations in Django need two steps. Those are “make migration” and “run migration”. In Rails, we create migrations for the models at the entire application level. But in Django we need to write all the fields required and the models methods in the model.py of the corresponding app.&lt;/p&gt;

&lt;p&gt;Note: Initially, we need to run the migrate command to run the default migrations.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;tr&gt;
&lt;td&gt;Rails
&lt;/td&gt;
&lt;td&gt;Django
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;rails db:migrate&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;python manage.py makemigrations&lt;/code&gt;
&lt;p&gt;
&lt;code&gt;python manage.py migrate&lt;/code&gt;
&lt;/p&gt;


&lt;/td&gt;
&lt;br&gt;
&lt;/tr&gt;
&lt;br&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Models:
&lt;/h3&gt;

&lt;p&gt;Both in Rails and Django models function as the same except for the fact that the fields of the model have to be mentioned in the model file in Django. But similar to Rails, we include the model methods and validations in the model file. In Django, model files are created in the app’s root directory.&lt;/p&gt;

&lt;h3&gt;
  
  
  View:
&lt;/h3&gt;

&lt;p&gt;In Django views are similar to the controller in Rails. They act as the interface between the model and template. We define the actions in the views.py in the corresponding app directory similarly like controllers in rails.&lt;/p&gt;

&lt;h3&gt;
  
  
  Template:
&lt;/h3&gt;

&lt;p&gt;In Django templates are similar as Views in Rails. In Django, Jinja2 is followed for the template format. Here all the templates are kept, in the template folder of each app’s root directory. Jinja2 is a template engine user in Django. Each view in Django returns an object which contains the data required in the template. Only the data available in the return object is accessible by the template, like the instance variable in rails.&lt;/p&gt;

&lt;p&gt;The basic elements in Jinja 2 are&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1. {%....%} are for statements
2. {{....}} are expressions used to print to template output
3. {#....#} are for comments which are not included in the template output
4. #....## are used as line statements
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  URLs:
&lt;/h3&gt;

&lt;p&gt;Urls.py are more like routes.rb in Rails. In Django, the URL specifies the view function for each path and action. The URLs corresponding to each app is available in the app’s root directory. Don’t forget to import views in the urls.py in the main project urls.py.&lt;/p&gt;

&lt;p&gt;One of the main changes, that has to be considered while working on Django is that we need to import the necessary library files in each model, view, and URL, unlike in Rails where everything is included when the app executes.&lt;/p&gt;

&lt;p&gt;I hope this gives a good idea for a Rails developer to get started with Django! Try it out and let me know what you think! :)&lt;/p&gt;

</description>
      <category>django</category>
      <category>rails</category>
      <category>python</category>
      <category>ruby</category>
    </item>
    <item>
      <title>Using Bamboo to Send Emails in Phoenix</title>
      <dc:creator>Heertheeswaran V</dc:creator>
      <pubDate>Fri, 18 Sep 2020 06:26:45 +0000</pubDate>
      <link>https://dev.to/heerthees/using-bamboo-to-send-emails-in-phoenix-529d</link>
      <guid>https://dev.to/heerthees/using-bamboo-to-send-emails-in-phoenix-529d</guid>
      <description>&lt;p&gt;Hey people! I’m back with another article based on my Phoenix learning.&lt;/p&gt;

&lt;p&gt;So to get to the point - in any application, one of the most important processes is sending emails to users. We are going to use the &lt;a href="https://github.com/thoughtbot/bamboo" rel="noopener noreferrer"&gt;&lt;strong&gt;Bamboo&lt;/strong&gt;&lt;/a&gt; library which supports all the major email providers and we can also use the HTML template for the email content.&lt;/p&gt;

&lt;p&gt;Here we will see the following:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Setting up Bamboo&lt;/li&gt;
&lt;li&gt;Sending users a welcome email once they sign up&lt;/li&gt;
&lt;li&gt;Using HTML to compose an email&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Ok, let’s get into this now. My main goal for this post is to have my app send a welcome email to the new signups. The app is a status management app that lets us know the current working status of fellow employees.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Setting up Bamboo:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;We’ll get started by adding the Bamboo dependency to our project’s &lt;strong&gt;mix.exs&lt;/strong&gt; file. Add bamboo to the &lt;strong&gt;deps&lt;/strong&gt; and &lt;strong&gt;application&lt;/strong&gt; function.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight viml"&gt;&lt;code&gt;mix&lt;span class="p"&gt;.&lt;/span&gt;exs
  &lt;span class="k"&gt;def&lt;/span&gt; application &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="k"&gt;mod&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;WorkStatus&lt;span class="p"&gt;.&lt;/span&gt;Application&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[]},&lt;/span&gt;
     applications&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[...&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;bamboo&lt;span class="p"&gt;]]&lt;/span&gt;
  end

  defp deps &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="p"&gt;[...&lt;/span&gt;
      &lt;span class="p"&gt;{:&lt;/span&gt;bamboo&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"~&amp;gt; 1.5"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;]&lt;/span&gt;
  end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, let us install the dependencies by using the command&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;mix deps.get
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let’s now define the “Mailer”, which is in charge of sending the email. We will create a mailer module in the “&lt;strong&gt;lib/workstatus (lib/:application)&lt;/strong&gt;” named “&lt;strong&gt;mailer.ex&lt;/strong&gt;”. Later on in this module, we will define a &lt;strong&gt;deliver&lt;/strong&gt; function that will be responsible for delivering the email.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight viml"&gt;&lt;code&gt;lib&lt;span class="sr"&gt;/workstatus/&lt;/span&gt;mailer&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;ex&lt;/span&gt;

defmodule Workstatus&lt;span class="p"&gt;.&lt;/span&gt;Mailer &lt;span class="k"&gt;do&lt;/span&gt;
  use Bamboo&lt;span class="p"&gt;.&lt;/span&gt;Mailer&lt;span class="p"&gt;,&lt;/span&gt; otp_app&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;workstatus

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

&lt;/div&gt;



&lt;p&gt;Now let us configure our development environment to use the &lt;code&gt;Bamboo.LocalAdapter&lt;/code&gt;. In the dev.exs, add the following,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight viml"&gt;&lt;code&gt;config/dev&lt;span class="p"&gt;.&lt;/span&gt;exs

config &lt;span class="p"&gt;:&lt;/span&gt;workstatus&lt;span class="p"&gt;,&lt;/span&gt; Workstatus&lt;span class="p"&gt;.&lt;/span&gt;Mailer&lt;span class="p"&gt;,&lt;/span&gt;
  adapter&lt;span class="p"&gt;:&lt;/span&gt; Bamboo&lt;span class="p"&gt;.&lt;/span&gt;LocalAdapter
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Bamboo.LocalAdapter allows us to view the sent emails in the development with the Bamboo.EmailPreviewPlug. To configure this, let us add the “/sent_emails” route and forward it to the Bamboo.SentEmailViewerPlug. Let’s add this in our “&lt;strong&gt;routes.ex&lt;/strong&gt;”.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight viml"&gt;&lt;code&gt;lib&lt;span class="sr"&gt;/workstatus_web/&lt;/span&gt;router&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;ex&lt;/span&gt;

 &lt;span class="k"&gt;if&lt;/span&gt; Mix&lt;span class="p"&gt;.&lt;/span&gt;env &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;dev &lt;span class="k"&gt;do&lt;/span&gt;
    forward &lt;span class="s2"&gt;"/sent_emails"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; Bamboo&lt;span class="p"&gt;.&lt;/span&gt;SentEmailViewerPlug
 end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This wraps up the setup required for the Bamboo. Now, let’s fire up our Phoenix server. If you get into any errors, please check the above steps once again.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;mix phoenix.server
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Adding the Mailer Functionality&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Bamboo separates the delivery and the composition of the mail. The delivery will be performed by the Mailer module. Let’s create an Email module that will perform the composition.&lt;/p&gt;

&lt;p&gt;Create a file called “email.ex” in the same directory of our Mailer module. We will import Bamboo.Email here, from which we will use the &lt;em&gt;new_email&lt;/em&gt; function to compose our email.&lt;/p&gt;

&lt;p&gt;Now, let’s create a function for welcoming users.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight viml"&gt;&lt;code&gt;lib&lt;span class="sr"&gt;/workstatus/&lt;/span&gt;email&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;ex&lt;/span&gt;

defmodule Workstatus&lt;span class="p"&gt;.&lt;/span&gt;Email &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="k"&gt;import&lt;/span&gt; Bamboo&lt;span class="p"&gt;.&lt;/span&gt;Email

  &lt;span class="k"&gt;def&lt;/span&gt; welcome_mail&lt;span class="p"&gt;(&lt;/span&gt;user&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    new_email&lt;span class="p"&gt;(&lt;/span&gt;
      from&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"no-reply@workstatus.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="k"&gt;to&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; user&lt;span class="p"&gt;.&lt;/span&gt;email&lt;span class="p"&gt;,&lt;/span&gt;
      subject&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"Welcome to WorkStatus!"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      text_body&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"Welcome to the WorkStatus!"&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For now let us, leave it with the text body. Later on in this post, we will see how to use the html template to compose the email.&lt;/p&gt;

&lt;p&gt;Now, let us add this in the &lt;em&gt;users_controller&lt;/em&gt; where the &lt;em&gt;sign_up&lt;/em&gt; is handled. To send the email, we will use the deliver function in the Bamboo library which will be imported in the Mailer module. Import both the Mailer and Email in the controller.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight viml"&gt;&lt;code&gt;lib&lt;span class="sr"&gt;/workstatus_web/&lt;/span&gt;contorollers/auth_contoroller&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;ex&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; signup&lt;span class="p"&gt;(&lt;/span&gt;%&lt;span class="p"&gt;{&lt;/span&gt;assigns&lt;span class="p"&gt;:&lt;/span&gt; %&lt;span class="p"&gt;{&lt;/span&gt;ueberauth_auth&lt;span class="p"&gt;:&lt;/span&gt; auth&lt;span class="p"&gt;}}&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; conn&lt;span class="p"&gt;,&lt;/span&gt; params&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  user_params &lt;span class="p"&gt;=&lt;/span&gt; %&lt;span class="p"&gt;{&lt;/span&gt;token&lt;span class="p"&gt;:&lt;/span&gt; auth&lt;span class="p"&gt;.&lt;/span&gt;credentials&lt;span class="p"&gt;.&lt;/span&gt;token&lt;span class="p"&gt;,&lt;/span&gt; email&lt;span class="p"&gt;:&lt;/span&gt; auth&lt;span class="p"&gt;.&lt;/span&gt;info&lt;span class="p"&gt;.&lt;/span&gt;email&lt;span class="p"&gt;,&lt;/span&gt; provider&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"github"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

  changeset &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;User&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;changeset&lt;span class="p"&gt;(&lt;/span&gt;%&lt;span class="nb"&gt;User&lt;/span&gt;&lt;span class="p"&gt;{},&lt;/span&gt; user_params&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;{:&lt;/span&gt;ok&lt;span class="p"&gt;,&lt;/span&gt; user&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; sign_in&lt;span class="p"&gt;(&lt;/span&gt;conn&lt;span class="p"&gt;,&lt;/span&gt; changeset&lt;span class="p"&gt;)&lt;/span&gt;
  Email&lt;span class="p"&gt;.&lt;/span&gt;welcome_mail&lt;span class="p"&gt;(&lt;/span&gt;user&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;|&amp;gt;&lt;/span&gt; Mailer&lt;span class="p"&gt;.&lt;/span&gt;deliver_later&lt;span class="p"&gt;()&lt;/span&gt;
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, once the user sign_up for the app, the welcome email will be sent. We can see the email that has been sent in the routes we defined earlier in the development environment.&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%2Fskcript.com%2Fsvrmedia%2Fheroes%2Fimage1-38.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%2Fskcript.com%2Fsvrmedia%2Fheroes%2Fimage1-38.png" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We can see the sent_email as in the above screenshot. Next, let us see how we can use the HTML to compose the email.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Using HTML to compose email:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;With HTML we can compose the email in a more elegant way. First, let’s create a view for our emails. Create a file “email_view.ex” in the views folder.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight viml"&gt;&lt;code&gt;workstatus_web&lt;span class="sr"&gt;/views/&lt;/span&gt;email_view&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;ex&lt;/span&gt;

defmodule Workstatus&lt;span class="p"&gt;.&lt;/span&gt;EmailView &lt;span class="k"&gt;do&lt;/span&gt;
  use WorkstatusWeb&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="k"&gt;view&lt;/span&gt;
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now let’s create the templates we need. Let’s start by creating our new email layout. Create a new &lt;strong&gt;“email.html.eex”&lt;/strong&gt; in the &lt;strong&gt;layouts&lt;/strong&gt; folder.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;workstatus_web/templates/layouts/email.html.eex

&lt;span class="nt"&gt;&amp;lt;html&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;link&lt;/span&gt; &lt;span class="na"&gt;rel=&lt;/span&gt;&lt;span class="s"&gt;"stylesheet"&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"&amp;lt;%= static_url(Workstatus.Endpoint, "&lt;/span&gt;&lt;span class="err"&gt;/&lt;/span&gt;&lt;span class="na"&gt;css&lt;/span&gt;&lt;span class="err"&gt;/&lt;/span&gt;&lt;span class="na"&gt;style.css&lt;/span&gt;&lt;span class="err"&gt;")&lt;/span&gt; &lt;span class="err"&gt;%&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;"&amp;gt;
  &lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"container"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="err"&gt;%=&lt;/span&gt; &lt;span class="na"&gt;render&lt;/span&gt; &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="na"&gt;view_module&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt; &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="na"&gt;view_template&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt; &lt;span class="na"&gt;assigns&lt;/span&gt; &lt;span class="err"&gt;%&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then we will create the template for our welcome_mail. Create a template in the &lt;strong&gt;templates/email&lt;/strong&gt; folder called &lt;strong&gt;welcome_mail.html.eex&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;workstatus_web/templates/email/welcome_mail.html.eex

&lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;Hi, &lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="err"&gt;%=&lt;/span&gt; &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="na"&gt;user.name&lt;/span&gt; &lt;span class="err"&gt;%&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"/images/phoenix.png"&lt;/span&gt; &lt;span class="na"&gt;alt=&lt;/span&gt;&lt;span class="s"&gt;"Phoenix Framework Logo"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let’s update our mailer function to render the created template. The updated welcome_mail function looks like.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight viml"&gt;&lt;code&gt;lib&lt;span class="sr"&gt;/workstatus/&lt;/span&gt;email&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;ex&lt;/span&gt;

defmodule Workstatus&lt;span class="p"&gt;.&lt;/span&gt;Email &lt;span class="k"&gt;do&lt;/span&gt;
  use Bamboo&lt;span class="p"&gt;.&lt;/span&gt;Phoenix&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;view&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; Workstatus&lt;span class="p"&gt;.&lt;/span&gt;EmailView
  &lt;span class="k"&gt;import&lt;/span&gt; Bamboo&lt;span class="p"&gt;.&lt;/span&gt;Email

  &lt;span class="k"&gt;def&lt;/span&gt; welcome_mailer&lt;span class="p"&gt;(&lt;/span&gt;user&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    new_email
      &lt;span class="p"&gt;|&amp;gt;&lt;/span&gt; from&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"no-reply@workstatus.com"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;to&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;user&lt;span class="p"&gt;.&lt;/span&gt;email&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;|&amp;gt;&lt;/span&gt; subject&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Welcome to WorkStatus!!"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;|&amp;gt;&lt;/span&gt; assign&lt;span class="p"&gt;(:&lt;/span&gt;user&lt;span class="p"&gt;,&lt;/span&gt; user&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;|&amp;gt;&lt;/span&gt; render&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"welcome_mail.html"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now the sent email looks like 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%2Fskcript.com%2Fsvrmedia%2Fheroes%2Fimage2-38.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%2Fskcript.com%2Fsvrmedia%2Fheroes%2Fimage2-38.png" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is a basic implementation of sending emails in Phoenix using Bamboo. This post is intended to be used as a Get Started guide. There are many more extensions and detailed explanations available in the &lt;a href="https://github.com/thoughtbot/bamboo" rel="noopener noreferrer"&gt;Bamboo Docs&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>phoenix</category>
      <category>beginners</category>
      <category>elixir</category>
      <category>mailer</category>
    </item>
    <item>
      <title>Create a Microsoft Teams Bot with Ruby on Rails and REST API</title>
      <dc:creator>Heertheeswaran V</dc:creator>
      <pubDate>Thu, 17 Sep 2020 11:35:13 +0000</pubDate>
      <link>https://dev.to/heerthees/create-a-microsoft-teams-bot-with-ruby-on-rails-and-rest-api-21i7</link>
      <guid>https://dev.to/heerthees/create-a-microsoft-teams-bot-with-ruby-on-rails-and-rest-api-21i7</guid>
      <description>&lt;p&gt;In this tutorial, we are going to build a bot using Microsoft Azure and use it in Microsoft Teams to interact with our Ruby on Rails Application. As of now, Microsoft Bot Framework supports SDK kit for Node js and C#. We will use the REST API to interact with the bot and perform operations.&lt;/p&gt;

&lt;p&gt;First, let’s start with creating a new app on the Azure platform,&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Create an App on the Azure Platform&lt;/strong&gt;
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Log in to Azure Portal.&lt;/li&gt;
&lt;li&gt;To create an app, go to Azure Active Directory -&amp;gt; App registrations -&amp;gt; New Registration.&lt;/li&gt;
&lt;/ol&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%2Fwww.skcript.com%2Fsvrmedia%2Fheroes%2Fimage3-2.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%2Fwww.skcript.com%2Fsvrmedia%2Fheroes%2Fimage3-2.png" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Take a note of the App ID from the Overview section. &lt;/li&gt;
&lt;/ol&gt;



&lt;ol&gt;
&lt;li&gt;Go to Certificated &amp;amp; secrets -&amp;gt; New Client secret and give a name and set expires to Never and click on Add.&lt;/li&gt;
&lt;/ol&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%2Fwww.skcript.com%2Fsvrmedia%2Fheroes%2Fimage5-2.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%2Fwww.skcript.com%2Fsvrmedia%2Fheroes%2Fimage5-2.png" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Take a note of the secret id generated as this cannot be viewed again.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;So, we have built an app with which we are going to create a bot service.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Create a Bot Service&lt;/strong&gt;
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Click &lt;strong&gt;Create new resource&lt;/strong&gt; link on the upper left-hand corner of the Azure portal, then select &lt;strong&gt;AI + Machine Learning&lt;/strong&gt; &amp;gt; &lt;strong&gt;Web App bot&lt;/strong&gt;.&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%2Fwww.skcript.com%2Fsvrmedia%2Fheroes%2Fimage2-4.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%2Fwww.skcript.com%2Fsvrmedia%2Fheroes%2Fimage2-4.png" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Fill up the form that opens up. In the Microsoft App ID and password section, give the app id and client secret as the password.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;After creating the bot, set the messaging endpoint to your Ruby on Rails API endpoint in the setting.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create an OAuth Connection Settings, fill the form.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Authorization URL: &lt;a href="https://login.microsoftonline.com/botframework.com/oauth2/v2.0/authorize" rel="noopener noreferrer"&gt;https://login.microsoftonline.com/botframework.com/oauth2/v2.0/authorize&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Token URL: &lt;a href="https://login.microsoftonline.com/botframework.com/oauth2/v2.0/token" rel="noopener noreferrer"&gt;https://login.microsoftonline.com/botframework.com/oauth2/v2.0/token&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Refresh URL: &amp;lt; YOUR REDIRECT URI &amp;gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Scopes: &amp;lt; YOUR REQUIRED SCOPES &amp;gt;&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%2Fwww.skcript.com%2Fsvrmedia%2Fheroes%2Fimage4-3.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%2Fwww.skcript.com%2Fsvrmedia%2Fheroes%2Fimage4-3.png" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;This OAuth Setting is required for your bot to work in MS Teams.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Test your bot in the Test Web Chat.&lt;/li&gt;
&lt;/ol&gt;


&lt;/li&gt;

&lt;/ol&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%2Fwww.skcript.com%2Fsvrmedia%2Fheroes%2Fimage1-4.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%2Fwww.skcript.com%2Fsvrmedia%2Fheroes%2Fimage1-4.png" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;REST API&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Since the bot and app are now set up in the Azure platform we are ready to work with them.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;User Authorization&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In order to authorize the app by user, the user is needed to be signed in and authorize the app with the link below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://login.microsoftonline.com/common/oauth2/v2.0/authorize?client_id=YOUR_CLIENT_ID&amp;amp;scope=YOUR_SCOPE&amp;amp;redirect_uri=YOUR_REDIRECT_URI&amp;amp;response_type=code" rel="noopener noreferrer"&gt;https://login.microsoftonline.com/common/oauth2/v2.0/authorize?client_id=YOUR_CLIENT_ID&amp;amp;scope=YOUR_SCOPE&amp;amp;redirect_uri=YOUR_REDIRECT_URI&amp;amp;response_type=code&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Bot Access Token&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To request an access token to interact with the bot, use the below request. The response token is a Bearer token.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;POST https://login.microsoftonline.com/botframework.com/oauth2/v2.0/token
Host: login.microsoftonline.com
Content-Type: application/x-www-form-urlencoded

grant_type=client_credentials&amp;amp;client_id=MICROSOFT-APP-ID&amp;amp;client_secret=MICROSOFT-APP-PASSWORD&amp;amp;scope=https://api.botframework.com/.default
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Response:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
"token_type":"Bearer",
"expires_in":3600,
"ext_expires_in":3600,
"access_token":"esadjnaskdnnaHs..."
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Create a Conversation&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;After getting a token, you can create a conversation with the user. To establish a conversation, use the following request to get the conversation id.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;POST &amp;lt; Service URL &amp;gt;/v3/conversations (https://smba.trafficmanager.net/in for  teams)
{
 "bot": {
   "id": "YOUR_BOT_ID",
   "name": "YOUR_BOT_NAME"
 },
 "members": [
   {
     "id": "USER_ID"
   }
 ],
 "channelData": {
   "tenant": {
     "id": "USERS_TENANT_ID"
   }
 }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Response:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{  
"id":"a:1sdadaa.."
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;After receiving the conversation, make a POST request to the activity to send a message like below.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;POST &amp;lt; Service URL&amp;gt;/v3/conversatoins/&amp;lt; Conversation id &amp;gt;/activities
{
 "bot": {
   "id": "YOUR_BOT_ID",
   "name": "YOUR_BOT_NAME"
 },
 "members": [
   {
     "id": "USER_ID"
   }
 ],
 "channelData": {
   "tenant": {
     "id": "USERS_TENANT_ID"
   }
 }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Reply to Conversation:&lt;/p&gt;

&lt;p&gt;In order to reply to a conversation with the following request, get the user id, name of the bot and user from the parameters of the initial message.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;POST &amp;lt;ServiceURL&amp;gt;/v3 /conversations/{conversationId}/activities/{activityId}
Authorization Bearer "eysdsda.." 
{
        "type": "message",
        "from": {"id": "&amp;lt; BOT_USER_ID&amp;gt;", "name": "&amp;lt;BOT_USER_NAME&amp;gt;"},
        "conversation": {"id": "IlbyD8hQi5aGqAAz3qXfVp-5"},
        "recipient": {"id": "&amp;lt;Receiver_user_id", "name": "&amp;lt;Receiver_user_name&amp;gt;"},
        "text": "This is a reply message."
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Updating a message:&lt;/p&gt;

&lt;p&gt;In order to update a message that is already sent, make the following request. You can get the replytoID from the initial message parameters&lt;/p&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;PUT &amp;lt;ServiceURL&amp;gt;/v3 /conversations/{ReplytoID}&lt;br&gt;
Authorization Bearer "eysdsda.." &lt;br&gt;
{&lt;br&gt;
   "type": "message",&lt;br&gt;
   "text": "This message has been updated"&lt;br&gt;
}&lt;br&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
&lt;br&gt;
  &lt;br&gt;
  &lt;br&gt;
  &lt;strong&gt;Test the bot in Teams:&lt;/strong&gt;&lt;br&gt;
&lt;/h3&gt;

&lt;p&gt;In order to test your bot in teams, you are required to add the Oauth connection as stated in the create a bot service section. Then you can just copy your bot app id and start a new conversation in teams with that id. Now you are all set to check your bot in Teams.&lt;/p&gt;




&lt;p&gt;So that’s it, people here is how you can easily create a basic bot and interact with ROR application. If you have any questions, leave them in the comments below.&lt;/p&gt;

</description>
      <category>ruby</category>
      <category>rails</category>
      <category>bot</category>
      <category>msteams</category>
    </item>
    <item>
      <title>Setting up OAuth in Phoenix</title>
      <dc:creator>Heertheeswaran V</dc:creator>
      <pubDate>Fri, 14 Aug 2020 06:02:26 +0000</pubDate>
      <link>https://dev.to/heerthees/setting-up-oauth-in-phoenix-2n21</link>
      <guid>https://dev.to/heerthees/setting-up-oauth-in-phoenix-2n21</guid>
      <description>&lt;p&gt;So, it’s been like a month since I started learning Elixir and the Phoenix. Phoenix is a web framework powered by Elixir and the Erlang VM, which makes it fast.&lt;/p&gt;

&lt;p&gt;In this post, we will see setting up “Sign in With Google” in a Phoenix application with &lt;a href="https://github.com/ueberauth/ueberauth" rel="noopener noreferrer"&gt;Ueberauth&lt;/a&gt;. We will be using the &lt;a href="https://github.com/ueberauth/ueberauth_google" rel="noopener noreferrer"&gt;ueberauth_google&lt;/a&gt; hex package to perform this.&lt;/p&gt;

&lt;p&gt;I’m going to assume that you have created the Phoenix app and created a user model. It should look similar to this.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight viml"&gt;&lt;code&gt;# user&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;ex&lt;/span&gt;
schema &lt;span class="s2"&gt;"users"&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    field &lt;span class="p"&gt;:&lt;/span&gt;email&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nb"&gt;string&lt;/span&gt;
    field &lt;span class="p"&gt;:&lt;/span&gt;first_name&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nb"&gt;string&lt;/span&gt;
    field &lt;span class="p"&gt;:&lt;/span&gt;last_name&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nb"&gt;string&lt;/span&gt;
    field &lt;span class="p"&gt;:&lt;/span&gt;provider&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nb"&gt;string&lt;/span&gt;
    field &lt;span class="p"&gt;:&lt;/span&gt;picture&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nb"&gt;string&lt;/span&gt;

    timestamps&lt;span class="p"&gt;()&lt;/span&gt;
  end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Adding Dependencies
&lt;/h3&gt;

&lt;p&gt;We will add the &lt;a href="https://github.com/ueberauth/ueberauth_google" rel="noopener noreferrer"&gt;ueberauth_google&lt;/a&gt; dependency to the &lt;strong&gt;deps&lt;/strong&gt; in the &lt;strong&gt;mix.exs.&lt;/strong&gt; Now, the mix.ex file looks like this.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight viml"&gt;&lt;code&gt; defp deps &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;
      &lt;span class="p"&gt;{:&lt;/span&gt;phoenix&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"~&amp;gt; 1.5.3"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="p"&gt;{:&lt;/span&gt;phoenix_ecto&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"~&amp;gt; 4.1"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="p"&gt;{:&lt;/span&gt;ecto_sql&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"~&amp;gt; 3.4"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="p"&gt;{:&lt;/span&gt;postgrex&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"&amp;gt;= 0.0.0"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="p"&gt;{:&lt;/span&gt;phoenix_live_view&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"~&amp;gt; 0.13.0"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="p"&gt;{:&lt;/span&gt;floki&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"&amp;gt;= 0.0.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;only&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;test&lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="p"&gt;{:&lt;/span&gt;phoenix_html&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"~&amp;gt; 2.11"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="p"&gt;{:&lt;/span&gt;phoenix_live_reload&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"~&amp;gt; 1.2"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;only&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;dev&lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="p"&gt;{:&lt;/span&gt;phoenix_live_dashboard&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"~&amp;gt; 0.2.0"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="p"&gt;{:&lt;/span&gt;telemetry_metrics&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"~&amp;gt; 0.4"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="p"&gt;{:&lt;/span&gt;telemetry_poller&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"~&amp;gt; 0.4"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="p"&gt;{:&lt;/span&gt;gettext&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"~&amp;gt; 0.11"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="p"&gt;{:&lt;/span&gt;jason&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"~&amp;gt; 1.0"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="p"&gt;{:&lt;/span&gt;plug_cowboy&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"~&amp;gt; 2.0"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="p"&gt;{:&lt;/span&gt;ueberauth_google&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"~&amp;gt; 0.9"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;]&lt;/span&gt;
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next we need to include this in the &lt;strong&gt;application&lt;/strong&gt; function in the &lt;strong&gt;mix.exs&lt;/strong&gt;. Now the application function looks like,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight viml"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; application &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;
      &lt;span class="k"&gt;mod&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;OAuthApp&lt;span class="p"&gt;.&lt;/span&gt;Application&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[]},&lt;/span&gt;
      extra_applications&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[:&lt;/span&gt;logger&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;runtime_tools&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;ueberauth_google&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="p"&gt;]&lt;/span&gt;
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After this run the following command to install the added dependencies. This will show the entire dependencies list including the ones we added now.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight viml"&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; mix deps&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;get&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Create a Google Project
&lt;/h3&gt;

&lt;p&gt;Create a Google project by following the steps given &lt;a href="https://developers.google.com/identity/sign-in/web/sign-in" rel="noopener noreferrer"&gt;here&lt;/a&gt;. The Google app will generate the &lt;em&gt;client_id&lt;/em&gt; and &lt;em&gt;client_secret&lt;/em&gt; that we need to configure in our app. In the Google app configurations, set the redirect_uri as “&lt;a href="http://localhost:4000/auth/google/callback%22" rel="noopener noreferrer"&gt;http://localhost:4000/auth/google/callback&lt;/a&gt;/”.&lt;/p&gt;

&lt;p&gt;&lt;a href="/svrmedia/heroes/image1-32.png" class="article-body-image-wrapper"&gt;&lt;img src="/svrmedia/heroes/image1-32.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Updating Configurations
&lt;/h3&gt;

&lt;p&gt;We will now add the configuration of our google app in our Phoenix application. Add the &lt;strong&gt;client id&lt;/strong&gt;, &lt;strong&gt;client secret,&lt;/strong&gt; and &lt;strong&gt;redirect_uri&lt;/strong&gt; to the &lt;strong&gt;config.exs&lt;/strong&gt; file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight viml"&gt;&lt;code&gt;# Ueberauth Config
config &lt;span class="p"&gt;:&lt;/span&gt;ueberauth&lt;span class="p"&gt;,&lt;/span&gt; Ueberauth&lt;span class="p"&gt;,&lt;/span&gt;
  providers&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    google&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;Ueberauth&lt;span class="p"&gt;.&lt;/span&gt;Strategy&lt;span class="p"&gt;.&lt;/span&gt;Google&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;default_scope&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"email profile"&lt;/span&gt;&lt;span class="p"&gt;]}&lt;/span&gt;
  &lt;span class="p"&gt;]&lt;/span&gt;
config &lt;span class="p"&gt;:&lt;/span&gt;ueberauth&lt;span class="p"&gt;,&lt;/span&gt; Ueberauth&lt;span class="p"&gt;.&lt;/span&gt;Strategy&lt;span class="p"&gt;.&lt;/span&gt;Google&lt;span class="p"&gt;.&lt;/span&gt;OAuth&lt;span class="p"&gt;,&lt;/span&gt;
  client_id&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"741231234148352289-e9asdasdmomm9lar1brbundnmfg3j80f04ntqt.apps.googleusercontent.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; # Dummy code
  client_secret&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"33uWw8WnPsadsdsSas7rjaTnkYbwu6"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; # Dummy code
  redirect_uri&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"http://localhost:4000/auth/google/callback"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we have done all the configurations needed, we will get into coding now.&lt;/p&gt;

&lt;h3&gt;
  
  
  Defining the Routes
&lt;/h3&gt;

&lt;p&gt;We will add the routes for sign in with google. We need the define the following routes in the &lt;strong&gt;routes.ex:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;OAuth Initiate - This initiates the OAuth process.&lt;/li&gt;
&lt;li&gt;OAuth Callback - This route is the route defined as redirect_uri in the google app configuration. We will get the user details in this callback call.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We will add these routes with the scope “/auth”. The code to be added to the router.ex looks like where provide is Google here. We can also use the same routes for any other social sign we need.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight viml"&gt;&lt;code&gt;scope &lt;span class="s2"&gt;"/auth"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; OAuthApp &lt;span class="k"&gt;do&lt;/span&gt;
    pipe_through &lt;span class="p"&gt;:&lt;/span&gt;browser

    &lt;span class="nb"&gt;get&lt;/span&gt; &lt;span class="s2"&gt;"/:provider"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; AuthController&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;request
    &lt;span class="nb"&gt;get&lt;/span&gt; &lt;span class="s2"&gt;"/:provider/callback"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; AuthController&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;callback
  end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Auth Controller
&lt;/h3&gt;

&lt;p&gt;We will now create a controller to handle the OAuth process.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Inside the &lt;strong&gt;controllers&lt;/strong&gt; folder, create a controller file called &lt;strong&gt;auth_controller.ex.&lt;/strong&gt; We will define the callback function here.&lt;/li&gt;
&lt;li&gt;We need to define two callback functions.

&lt;ul&gt;
&lt;li&gt;OAuth Success Case&lt;/li&gt;
&lt;li&gt;OAuth Failure Case&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h3&gt;
  
  
  OAuth Failure Case
&lt;/h3&gt;

&lt;p&gt;The Ueberauth send the failure response in the below mentioned format. So, we need to define a callback function to match the failure pattern. If the “assigns” variable has the key “ueberauth_failure”, it indicates that the authorization failed.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight viml"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; callback&lt;span class="p"&gt;(&lt;/span&gt;%&lt;span class="p"&gt;{&lt;/span&gt;assigns&lt;span class="p"&gt;:&lt;/span&gt; %&lt;span class="p"&gt;{&lt;/span&gt;ueberauth_failure&lt;span class="p"&gt;:&lt;/span&gt; _fails&lt;span class="p"&gt;}}&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; conn&lt;span class="p"&gt;,&lt;/span&gt; _params&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    conn
    &lt;span class="p"&gt;|&amp;gt;&lt;/span&gt; put_flash&lt;span class="p"&gt;(:&lt;/span&gt;error&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"Failed to authenticate."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;|&amp;gt;&lt;/span&gt; redirect&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;to&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"/"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  OAuth Success Case
&lt;/h3&gt;

&lt;p&gt;If the failure key is not present then the authorization is successful and it sends the oauth response in the key “ueberauth_auth” in the response. So, we need to define the callback function to match the response pattern.&lt;/p&gt;

&lt;p&gt;Like in the code below, we can match the user information and send it to the user changeset and based on the use case either create or update the user details.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight viml"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; callback&lt;span class="p"&gt;(&lt;/span&gt;%&lt;span class="p"&gt;{&lt;/span&gt;assigns&lt;span class="p"&gt;:&lt;/span&gt; %&lt;span class="p"&gt;{&lt;/span&gt;ueberauth_auth&lt;span class="p"&gt;:&lt;/span&gt; auth&lt;span class="p"&gt;}}&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; conn&lt;span class="p"&gt;,&lt;/span&gt; _params&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    user_params &lt;span class="p"&gt;=&lt;/span&gt; %&lt;span class="p"&gt;{&lt;/span&gt;
      first_name&lt;span class="p"&gt;:&lt;/span&gt; auth&lt;span class="p"&gt;.&lt;/span&gt;info&lt;span class="p"&gt;.&lt;/span&gt;first_name&lt;span class="p"&gt;,&lt;/span&gt;
      last_name&lt;span class="p"&gt;:&lt;/span&gt; auth&lt;span class="p"&gt;.&lt;/span&gt;info&lt;span class="p"&gt;.&lt;/span&gt;last_name&lt;span class="p"&gt;,&lt;/span&gt;
      email&lt;span class="p"&gt;:&lt;/span&gt; auth&lt;span class="p"&gt;.&lt;/span&gt;info&lt;span class="p"&gt;.&lt;/span&gt;email&lt;span class="p"&gt;,&lt;/span&gt;
      picture&lt;span class="p"&gt;:&lt;/span&gt; auth&lt;span class="p"&gt;.&lt;/span&gt;info&lt;span class="p"&gt;.&lt;/span&gt;image&lt;span class="p"&gt;,&lt;/span&gt;
      provider&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"google"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    changeset &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;User&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;changeset&lt;span class="p"&gt;(&lt;/span&gt;%&lt;span class="nb"&gt;User&lt;/span&gt;&lt;span class="p"&gt;{},&lt;/span&gt; user_params&lt;span class="p"&gt;)&lt;/span&gt;

    case insert_or_update_user&lt;span class="p"&gt;(&lt;/span&gt;changeset&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
      &lt;span class="p"&gt;{:&lt;/span&gt;ok&lt;span class="p"&gt;,&lt;/span&gt; user&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt;
        conn
        &lt;span class="p"&gt;|&amp;gt;&lt;/span&gt; put_flash&lt;span class="p"&gt;(:&lt;/span&gt;info&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"Thank you for signing in!"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;|&amp;gt;&lt;/span&gt; put_session&lt;span class="p"&gt;(:&lt;/span&gt;user_id&lt;span class="p"&gt;,&lt;/span&gt; user&lt;span class="p"&gt;.&lt;/span&gt;id&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;|&amp;gt;&lt;/span&gt; redirect&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;to&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; Routes&lt;span class="p"&gt;.&lt;/span&gt;lobby_path&lt;span class="p"&gt;(&lt;/span&gt;conn&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nb"&gt;index&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

      &lt;span class="p"&gt;{:&lt;/span&gt;error&lt;span class="p"&gt;,&lt;/span&gt; _reason&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt;
        conn
        &lt;span class="p"&gt;|&amp;gt;&lt;/span&gt; put_flash&lt;span class="p"&gt;(:&lt;/span&gt;error&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"Error signing in"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;|&amp;gt;&lt;/span&gt; redirect&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;to&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; Routes&lt;span class="p"&gt;.&lt;/span&gt;page_path&lt;span class="p"&gt;(&lt;/span&gt;conn&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nb"&gt;index&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    end
  end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Yay! Now, you have successfully used Google OAuth to authenticate your users. &lt;/p&gt;

&lt;p&gt;In this article, we discussed implementing Sign in with Google in our Phoenix application. Ueberauth provides OAuth for most of the social platforms such as Facebook, Twitter. WIth this we can also get the user token from the OAuth response and play with the Google APi to integrate google apps like Google Calendar, Google Meet. With this, the user does not have to remember a password which gives a good user experience.&lt;/p&gt;

&lt;p&gt;If you find any difficulties, reach out to &lt;a href="//mailto:heerthees@skcript.com"&gt;heerthees@skcript.com&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>elixir</category>
      <category>phoenix</category>
    </item>
    <item>
      <title>Build a Simple Web App using Go</title>
      <dc:creator>Heertheeswaran V</dc:creator>
      <pubDate>Sun, 24 May 2020 14:57:01 +0000</pubDate>
      <link>https://dev.to/heerthees/build-a-simple-web-app-using-go-29ad</link>
      <guid>https://dev.to/heerthees/build-a-simple-web-app-using-go-29ad</guid>
      <description>&lt;p&gt;Hello everyone, Today I would like to discuss building a simple hello world web app with Golang. Go is already has a web server built-in. The "net/http" package from the standard library contains all the things we need to do with the HTTP protocol. In this example, we will see how easy it is to run a web server that we can see in our browser.&lt;/p&gt;

&lt;p&gt;For creating a webserver in go, we need to understand two main functions.&lt;/p&gt;

&lt;h1&gt;
  
  
  Request Handler
&lt;/h1&gt;

&lt;p&gt;As the name suggests, the Request Handler is the one which receives all the http connections from the browser. The syntax of the Request Handler function is&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;code&gt;func (w http.ResponseWriter, r *http.Request)&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;The handler function receives two arguments:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;http.Request - contains all details about the HTTP request including things like the URL, header or body fields.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;http.ResponseWriter - where we write out a response to.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;So first, we need to register a Handler function. &lt;/p&gt;

&lt;h1&gt;
  
  
  Request Listener
&lt;/h1&gt;

&lt;p&gt;The Request Handler function can only receive the http connections. Along with that, we need a Request Listener which listens on a port and passes the connection to the Handler function. &lt;/p&gt;

&lt;p&gt;The syntax of a listner function is&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;code&gt;http.ListenAndServe(":3000", nil)&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;The listener function receives two arguments:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;port - The port to listen for the http connections.&lt;/li&gt;
&lt;li&gt;handler - the handler to send all the connection. Typically the handler is nil.&lt;/li&gt;
&lt;/ol&gt;

&lt;h1&gt;
  
  
  Hello World Web App
&lt;/h1&gt;

&lt;p&gt;By understanding the above function, it is simple to create a web server. The code for a simple hello world web server looks 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;// main.go
package main

import (
    "fmt"
    "net/http"
)
func main() {
  http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "Hello, World!") 
  })
  http.ListenAndServe(":3000", nil)
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run the main.go using the command&lt;br&gt;
&lt;br&gt;
 &lt;code&gt;go run main.go&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fvo0tioh3wk58yn1p8tst.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fvo0tioh3wk58yn1p8tst.png" alt="Alt Text" width="736" height="111"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So, if we now go to the browser and open &lt;a href="http://localhost:3000/" rel="noopener noreferrer"&gt;http://localhost:3000/&lt;/a&gt; we can see the "Hello, World!" text which we are returning. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F96i32vwcb0xbaka7kzyx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F96i32vwcb0xbaka7kzyx.png" alt="Alt Text" width="432" height="173"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this example, the handler function is mapper to the root path which is "/". Likewise, we can create multiple routes and register them to their corresponding handlers.&lt;/p&gt;

&lt;p&gt;All done! 🎉&lt;/p&gt;

&lt;p&gt;That’s it for now guys. Will meet you guys again with another interesting topic.&lt;/p&gt;

</description>
      <category>go</category>
      <category>webapplication</category>
      <category>beginners</category>
    </item>
    <item>
      <title>GO for GO</title>
      <dc:creator>Heertheeswaran V</dc:creator>
      <pubDate>Thu, 17 Oct 2019 05:10:44 +0000</pubDate>
      <link>https://dev.to/heerthees/get-started-with-go-2a0g</link>
      <guid>https://dev.to/heerthees/get-started-with-go-2a0g</guid>
      <description>&lt;p&gt;I started to learn Go a few weeks ago as a hobby. In this article series, I will document everything I learn.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is GO?
&lt;/h3&gt;

&lt;p&gt;As all probably know, Go is a general-purpose language developed by Google and has a wide range of applications. Go takes us back to the syntax of C++.&lt;/p&gt;

&lt;p&gt;The most important feature of Go is its concurrency. It allows multiple processes to run simultaneously and effectively thanks to its garbage collector, goroutines (a lightweight thread managed by Go for efficient concurrency) and channels. And of course, GO is an open-source language.&lt;/p&gt;

&lt;p&gt;So, let’s now dive into the workspace setup.&lt;/p&gt;

&lt;h3&gt;
  
  
  Setting Up Workspace:
&lt;/h3&gt;

&lt;p&gt;The go program is made up of packages. The package acts as an entry point for an application. Before you start crushing it on Go, we need to set up a workspace. A normal Go workspace looks like this:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;bin/
    hello                          # command executable
    outyet                         # command executable
src/
    github.com/golang/example/
        .git/                      # Git repository metadata
    hello/
        hello.go               # command source
    outyet/
        main.go                # command source
        main_test.go           # test source
    stringutil/
        reverse.go             # package source
        reverse_test.go        # test source
    golang.org/x/image/
        .git/                      # Git repository metadata
    bmp/
        reader.go              # package source
        writer.go              # package source
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;A typical workspace contains many source repositories containing many packages and commands. Most Go programmers keep all their Go source code and dependencies in a single workspace.&lt;/p&gt;

&lt;p&gt;The tree above shows a workspace containing two repositories (&lt;code&gt;example&lt;/code&gt; and &lt;code&gt;image&lt;/code&gt;). The example repository contains two commands (&lt;code&gt;hello&lt;/code&gt; and &lt;code&gt;outyet&lt;/code&gt;) and one library (&lt;code&gt;stringutil&lt;/code&gt;). The image repository contains the bmp package and &lt;a href="https://godoc.org/golang.org/x/image" rel="noopener noreferrer"&gt;several others&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The GOPATH environment variable specifies the location of your workspace. Set the GOPATH variable to your desired directory by using the command below:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export GOPATH = &amp;lt;desired directory&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
  
  
  A simple Go program:
&lt;/h3&gt;

&lt;p&gt;We can now dive into writing a simple Go program. I have set my Go workspace as shown below. My GOPATH variable is set to my “go_workspace”.&lt;/p&gt;

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

&lt;p&gt;I have created the package folder “&lt;code&gt;simple_program&lt;/code&gt;” in the src folder under the corresponding repository. Let’s now write a simple go program in “&lt;code&gt;simple_program/simple_program.go&lt;/code&gt;”&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;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;"fmt"&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;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;"This is a simple go program."&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;
  
  
  Executing a GO program:
&lt;/h3&gt;

&lt;p&gt;As said earlier, package main acts as the entry point. There are two ways you can run a go program&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Build as an executable and run. To build the Go program as an executable in the program directory run the command - &lt;code&gt;go build file_name.go&lt;/code&gt; or  &lt;code&gt;go install file_name.go&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The Go build command creates an executable file in the current directory which can be executed as below: &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhxrk4zzrozkqpjvymylp.png" alt="Alt Text" width="408" height="147"&gt;
&lt;/li&gt;
&lt;li&gt;The Go install command - created an executable file in the bin folder of the GOPATH and this bin can be added to our environment PATH and can be used anywhere. &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwfad7lp31ynh7t8kz4p8.png" alt="Alt Text" width="637" height="178"&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;&lt;p&gt;The simple way to run is by using the command - &lt;code&gt;go run file_name.go.&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;

&lt;/ul&gt;

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

&lt;p&gt;That’s it for now guys. Will meet you guys again with another interesting topic.&lt;/p&gt;

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