<?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: Johan Lejdung</title>
    <description>The latest articles on DEV Community by Johan Lejdung (@johanlejdung).</description>
    <link>https://dev.to/johanlejdung</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%2F209765%2Fb7371026-813d-40d7-8b38-afd5905b1b4d.jpg</url>
      <title>DEV Community: Johan Lejdung</title>
      <link>https://dev.to/johanlejdung</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/johanlejdung"/>
    <language>en</language>
    <item>
      <title>A mini-guide - Go Modules and Private Repositories</title>
      <dc:creator>Johan Lejdung</dc:creator>
      <pubDate>Sat, 06 Feb 2021 11:53:10 +0000</pubDate>
      <link>https://dev.to/johanlejdung/a-mini-guide-go-modules-and-private-repositories-4c7o</link>
      <guid>https://dev.to/johanlejdung/a-mini-guide-go-modules-and-private-repositories-4c7o</guid>
      <description>&lt;p&gt;The official dependency management system Go Modules have been supported since Go 1.11, and has since exploded in use. As of 2020 of the adoption of Go Modules has risen to &lt;a href="https://www.jetbrains.com/lp/devecosystem-2020/go/"&gt;82% among developers&lt;/a&gt;. &lt;/p&gt;

&lt;h1&gt;
  
  
  Brief Background
&lt;/h1&gt;

&lt;p&gt;Before Go Modules were a thing, there was a variety of community-created dependency management systems such as dep, godep, and govendor. All of these tried to solve the issue of managing the package versions used in applications.&lt;/p&gt;

&lt;p&gt;You might not even have heard about &lt;code&gt;$GOPATH&lt;/code&gt;, but this used to be something every Go developer had to wrap their heads around. &lt;code&gt;$GOPATH&lt;/code&gt; is the path to the location of your workspace, all of your code had to live within this space before Go Modules. That meant that you weren't able to put your code anywhere you wanted, Go Modules changed all of that and now allows developers to place their code wherever they please as long as they have a &lt;code&gt;go.mod&lt;/code&gt; file in the directory.&lt;/p&gt;

&lt;h1&gt;
  
  
  Go Modules
&lt;/h1&gt;

&lt;p&gt;One of the first things you want to do after creating a folder or repository for your new project is to name the module. You typically name it the same as the path to your repository, such as: &lt;em&gt;github.com/johan-lejdung/my-repo&lt;/em&gt; but you are free to name it whatever you want. &lt;/p&gt;

&lt;p&gt;You create the module with the following command&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="n"&gt;go&lt;/span&gt; &lt;span class="n"&gt;mod&lt;/span&gt; &lt;span class="kd"&gt;init&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;johan&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;lejdung&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;my&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;repo&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After you've run the command there is a &lt;code&gt;go.mod&lt;/code&gt; and &lt;code&gt;go.sum&lt;/code&gt; file in your repository, in the interest to keep this article brief feel free to read more about these two files over at &lt;a href="https://golangbyexample.com/go-mod-sum-module/"&gt;this post&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The beauty of Go Modules is that you won't have to update the dependencies yourself, most built-in Go commands will automatically update the dependencies in your code as you run it. So whenever you build, run or fetch a package it’s all updated automatically.&lt;/p&gt;

&lt;p&gt;Read more about Go Modules &lt;a href="https://blog.golang.org/using-go-modules"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  Private Repositories
&lt;/h1&gt;

&lt;p&gt;If you have your code in a private repository you might have issues accessing it and are presented with errors such as &lt;code&gt;410 Gone&lt;/code&gt;. Go 1.13 introduced a new environmental variable &lt;code&gt;$GOPRIVATE&lt;/code&gt; . &lt;/p&gt;

&lt;p&gt;From: &lt;a href="https://tip.golang.org/cmd/go/#hdr-Configuration_for_downloading_non_public_code"&gt;tip.golang.org&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The GOPRIVATE environment variable controls which modules the go command considers to be private (not available publicly) and should therefore not use the proxy or checksum database. The variable is a comma-separated list of glob patterns (in the syntax of Go's path.Match) of module path prefixes. For example,&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kt"&gt;GOPRIVATE&lt;/span&gt;&lt;span class="o"&gt;=*.&lt;/span&gt;&lt;span class="n"&gt;corp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;example&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;com&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;rsc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;io&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="kd"&gt;private&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;causes the go command to treat as private any module with a path prefix matching either pattern, including &lt;a href="http://git.corp.example.com/xyzzy"&gt;git.corp.example.com/xyzzy&lt;/a&gt;, &lt;a href="http://rsc.io/private"&gt;rsc.io/private&lt;/a&gt;, and &lt;a href="http://rsc.io/private/quux"&gt;rsc.io/private/quux&lt;/a&gt;. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;To be able to access your private repository you will need to set your &lt;code&gt;$GOPRIVATE&lt;/code&gt; with the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="n"&gt;go&lt;/span&gt; &lt;span class="n"&gt;env&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt; &lt;span class="kt"&gt;GOPRIVATE&lt;/span&gt;&lt;span class="o"&gt;=&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;repoURL&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="kd"&gt;private&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;repo&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can also include all repositories under an organization or provide a comma-separated list of individual repositories.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="n"&gt;go&lt;/span&gt; &lt;span class="n"&gt;env&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt; &lt;span class="kt"&gt;GOPRIVATE&lt;/span&gt;&lt;span class="o"&gt;=&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;/&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;OrgNameHere&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;/*&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you are using SSH to access your Git Repository you should consider adding the following to your &lt;code&gt;~/.ssh/config&lt;/code&gt; file to enable the Go command to access the git service:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kt"&gt;Host&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="kt"&gt;AddKeysToAgent&lt;/span&gt; &lt;span class="n"&gt;yes&lt;/span&gt;
 &lt;span class="kt"&gt;UseKeychain&lt;/span&gt; &lt;span class="n"&gt;yes&lt;/span&gt;
 &lt;span class="kt"&gt;IdentityFile&lt;/span&gt; &lt;span class="o"&gt;~/.&lt;/span&gt;&lt;span class="n"&gt;ssh&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;id_github&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Where &lt;code&gt;~/.ssh/id_github&lt;/code&gt; is the private key for your SSH authentication. The same setup should work with other repositories such as Gitlab and Bitbucket.&lt;/p&gt;

&lt;p&gt;If you are using SSH to access a &lt;strong&gt;local Git Repository&lt;/strong&gt; you should add the following to your &lt;code&gt;~/.gitconfig&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt; &lt;span class="s"&gt;"ssh://git@git.local.intranet/"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

       &lt;span class="n"&gt;insteadOf&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;https&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="c1"&gt;//git.local.intranet/&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I hope you have enjoyed this mini-guide. For updates on new articles and content from me, follow me on twitter &lt;a href="https://twitter.com/JohanLejdung"&gt;@JohanLejdung&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>go</category>
      <category>beginners</category>
      <category>webdev</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Pitching your idea - Things I've learned</title>
      <dc:creator>Johan Lejdung</dc:creator>
      <pubDate>Thu, 10 Dec 2020 21:25:48 +0000</pubDate>
      <link>https://dev.to/johanlejdung/pitching-your-idea-things-i-ve-learned-49fj</link>
      <guid>https://dev.to/johanlejdung/pitching-your-idea-things-i-ve-learned-49fj</guid>
      <description>&lt;p&gt;Whether you are working hard on a side project, or just started building your company you are going to communicate your idea sometime. And most likely you are going to want someone to invest time or money in your idea.&lt;/p&gt;

&lt;p&gt;I’ve been doing a lot of pitches together with my cofounder for our startup &lt;a href="https://www.chaintraced.com"&gt;ChainTraced&lt;/a&gt; lately. As a practise I’ve written down a couple of reflections and things I’ve learned.&lt;/p&gt;

&lt;p&gt;I’m going to keep it short and consice, so lets dig in! 📚&lt;/p&gt;




&lt;h2&gt;
  
  
  Presenting in person 🎤
&lt;/h2&gt;

&lt;p&gt;Practise your on-stage energy, posture and tone of voice. Looking calm and secure is more imporant than you might think. Competition is fierce! You want to stand out in every positive way you can and you don’t want to bore your listeners.&lt;/p&gt;

&lt;h2&gt;
  
  
  With slides in person 🌟
&lt;/h2&gt;

&lt;p&gt;Use the slides to enhance your pitch, but don't count on them to carry the entire pitch. Interact with your slides as a presenter, guide your audience through the presentation. Replace long text with images, graphs, titles and list/points. Reduce potential distractions in the slides, such as moving images and too much text.&lt;/p&gt;




&lt;h2&gt;
  
  
  More than one? 😄😅
&lt;/h2&gt;

&lt;p&gt;If possible, avoid having too many people present. Synchronise your on-stage energies and tone of voice and make sure the hand-offs are woven into the presentation, don’t switch back and forth. Especially if there is a microphone or other physical item involved. The slight pause needed to transfer the item is enough to ruin the flow.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Cx80BxTT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/vm1jfj2y82oo6d9rewbz.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Cx80BxTT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/vm1jfj2y82oo6d9rewbz.jpg" alt="william-iven-gcsNOsPEXfs-unsplash"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Online pitch 🧑‍💻
&lt;/h2&gt;

&lt;p&gt;If you are pitching online, give a bit more attention to the presentation. Make sure it looks good, has a coherent flow and doesn’t have distractions in it. Guiding the listener through your presentation is more important now that you are online, you can’t physically point at the slides so make sure they are self explanatory or make use of animations.&lt;/p&gt;




&lt;h2&gt;
  
  
  Time it! ⏱
&lt;/h2&gt;

&lt;p&gt;Make sure that your pitch doesn't go on for too long, or too short. Depending on the platform you are presenting on, you want to make sure you have time for questions or at the very least book a followup meeting if you are talking to an investor.&lt;/p&gt;




&lt;h2&gt;
  
  
  Know your content 📚
&lt;/h2&gt;

&lt;p&gt;I’m not much for practicing, but that doesn’t stop me from studying. If you know your content you are prepared to go "off script" if needed. A little bit of practicing together with a deep knowledge of the content have served me well.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--9zCiJ709--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/yq5r05g36cm2letm6kbi.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--9zCiJ709--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/yq5r05g36cm2letm6kbi.jpg" alt="andrew-neel--FVaZbu6ZAE-unsplash"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Build story 💭
&lt;/h2&gt;

&lt;p&gt;Make your pitch engaging by building a story around the problem you are solving. Done correctly, this engages the audience to want to understand the problem and how you are solving it. Engagement obviously greatly increases your chances to stand out 👏&lt;/p&gt;




&lt;h2&gt;
  
  
  Keep it simple 🏕
&lt;/h2&gt;

&lt;p&gt;Don’t underestimate the complexity of the problem and your solution. Replace jargon with common words, and don’t go overboard on explanations. Try the pitch on a family member or a friend to help identify the pain points, where they fall off.&lt;/p&gt;




&lt;p&gt;I hope this has been of use, either way it was a good practice for me to writing down some reflections. I don’t do it nearly enough 🙃 I'd love to hear your thoughts and comments.&lt;/p&gt;

&lt;p&gt;If you liked this micro-blog sharing it with friends on Twitter is greatly appreciated! &lt;/p&gt;
&lt;blockquote class="ltag__twitter-tweet"&gt;
      &lt;div class="ltag__twitter-tweet__media ltag__twitter-tweet__media__video-wrapper"&gt;
        &lt;div class="ltag__twitter-tweet__media--video-preview"&gt;
          &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--UdS4RPJa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://pbs.twimg.com/tweet_video_thumb/Eo0bRH8XMAM4RaM.jpg" alt="unknown tweet media content"&gt;
          &lt;img src="/assets/play-butt.svg" class="ltag__twitter-tweet__play-butt" alt="Play butt"&gt;
        &lt;/div&gt;
        &lt;div class="ltag__twitter-tweet__video"&gt;
          
            
          
        &lt;/div&gt;
      &lt;/div&gt;

  &lt;div class="ltag__twitter-tweet__main"&gt;
    &lt;div class="ltag__twitter-tweet__header"&gt;
      &lt;img class="ltag__twitter-tweet__profile-image" src="https://res.cloudinary.com/practicaldev/image/fetch/s--tfOadCwE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://pbs.twimg.com/profile_images/533644557284429824/5fxUYptp_normal.jpeg" alt="Johan Lejdung profile image"&gt;
      &lt;div class="ltag__twitter-tweet__full-name"&gt;
        Johan Lejdung
      &lt;/div&gt;
      &lt;div class="ltag__twitter-tweet__username"&gt;
        &lt;a class="comment-mentioned-user" href="https://dev.to/johanlejdung"&gt;@johanlejdung&lt;/a&gt;

      &lt;/div&gt;
      &lt;div class="ltag__twitter-tweet__twitter-logo"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ir1kO05j--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/twitter-f95605061196010f91e64806688390eb1a4dbc9e913682e043eb8b1e06ca484f.svg" alt="twitter logo"&gt;
      &lt;/div&gt;
    &lt;/div&gt;
    &lt;div class="ltag__twitter-tweet__body"&gt;
      I’ve been doing a lot of pitches together with my cofounder for our &lt;a href="https://twitter.com/hashtag/startup"&gt;#startup&lt;/a&gt; ChainTraced lately. As a practise I’ve written down a couple of reflections and things I’ve learned 😊 Most of these should apply for other kinds of presentations too&lt;br&gt;&lt;br&gt;Thread 🧵&lt;br&gt;&lt;br&gt;&lt;a href="https://twitter.com/hashtag/vc"&gt;#vc&lt;/a&gt; &lt;a href="https://twitter.com/hashtag/presenting"&gt;#presenting&lt;/a&gt; &lt;a href="https://twitter.com/hashtag/pitch"&gt;#pitch&lt;/a&gt; 
    &lt;/div&gt;
    &lt;div class="ltag__twitter-tweet__date"&gt;
      19:28 PM - 09 Dec 2020
    &lt;/div&gt;


    &lt;div class="ltag__twitter-tweet__actions"&gt;
      &lt;a href="https://twitter.com/intent/tweet?in_reply_to=1336754652419919878" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--fFnoeFxk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/twitter-reply-action-238fe0a37991706a6880ed13941c3efd6b371e4aefe288fe8e0db85250708bc4.svg" alt="Twitter reply action"&gt;
      &lt;/a&gt;
      &lt;a href="https://twitter.com/intent/retweet?tweet_id=1336754652419919878" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--k6dcrOn8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/twitter-retweet-action-632c83532a4e7de573c5c08dbb090ee18b348b13e2793175fea914827bc42046.svg" alt="Twitter retweet action"&gt;
      &lt;/a&gt;
      &lt;a href="https://twitter.com/intent/like?tweet_id=1336754652419919878" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--SRQc9lOp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/twitter-like-action-1ea89f4b87c7d37465b0eb78d51fcb7fe6c03a089805d7ea014ba71365be5171.svg" alt="Twitter like action"&gt;
      &lt;/a&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/blockquote&gt;


&lt;p&gt;Images (in order):&lt;br&gt;
&lt;span&gt;Photo by &lt;a href="https://unsplash.com/@tool_inc?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Tool., Inc&lt;/a&gt; on &lt;a href="https://unsplash.com/s/photos/presenting?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Unsplash&lt;/a&gt;&lt;/span&gt;&lt;br&gt;
&lt;span&gt;Photo by &lt;a href="https://unsplash.com/@firmbee?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;William Iven&lt;/a&gt; on &lt;a href="https://unsplash.com/s/photos/online-pitch?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Unsplash&lt;/a&gt;&lt;/span&gt;&lt;br&gt;
&lt;span&gt;Photo by &lt;a href="https://unsplash.com/@andrewtneel?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Andrew Neel&lt;/a&gt; on &lt;a href="https://unsplash.com/s/photos/story?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Unsplash&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;

</description>
      <category>discuss</category>
      <category>pitch</category>
      <category>presenting</category>
      <category>speaking</category>
    </item>
    <item>
      <title>A mini-guide — Middleware, and how it works in Go</title>
      <dc:creator>Johan Lejdung</dc:creator>
      <pubDate>Tue, 22 Oct 2019 18:28:13 +0000</pubDate>
      <link>https://dev.to/johanlejdung/a-mini-guide-middleware-and-how-it-works-in-go-4coj</link>
      <guid>https://dev.to/johanlejdung/a-mini-guide-middleware-and-how-it-works-in-go-4coj</guid>
      <description>&lt;p&gt;In this article I will explain the concept of middleware and create a working example in Go. The code for the complete project will be linked at the end of the article.&lt;/p&gt;

&lt;p&gt;The article is written as a companion piece to my previous article &lt;a href="https://dev.to/johanlejdung/a-mini-guide-build-a-rest-api-as-a-go-microservice-together-with-mysql-27m2"&gt;A mini-guide — Build a REST API as a Go microservice together with MySQL&lt;/a&gt;. Although this article is standalone and will be readable and understandable without having read the other one beforehand.&lt;/p&gt;

&lt;p&gt;This code is using Go Modules, if you are unfamiliar with Go Modules read about it in &lt;a href="https://dev.to/johanlejdung/a-mini-guide-go-modules-and-private-repositories-4c7o"&gt;this other article of mine&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Let’s dive in! &amp;lt;⌨&amp;gt;️&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Middleware, what even are they?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you are already familiar with Middleware and just want to get to the action, you can skip this section.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/Qe5oD5aXjEbKw/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/Qe5oD5aXjEbKw/giphy.gif" alt="Middleware, what even are they?"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;If you feel like Ryan Reynolds above when I mention Middleware, I got you covered 🤗&lt;/p&gt;

&lt;p&gt;In the world of networking a middleware is code that executes on network-based requests made by a client, which will then chain the request to the next middleware and eventually the final executing function. This is useful when you want to separate operations shared across multiple endpoints, such as: authentication, performance logging and data collection.&lt;/p&gt;

&lt;p&gt;As an example; let’s say we have an endpoint that returns a list of messages posted by a user, and another that returns sensitive personal information about that user.&lt;/p&gt;

&lt;p&gt;Both endpoints are only accessible when the user is logged into the service. Additionally, we also want to log the execution time of each request made to our server. The code for the authentication and logging could be written together with the controller and copied over to the two endpoints. But the example is easily split into four different packages.&lt;/p&gt;

&lt;p&gt;One that &lt;strong&gt;logs data about the request (LOG)&lt;/strong&gt;, one that &lt;strong&gt;verifies that the user is logged in (AUTH)&lt;/strong&gt;, one that &lt;strong&gt;returns a list of messages (RETURN MSG)&lt;/strong&gt; and one that &lt;strong&gt;returns user data (RETURN USER)&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;By writing these functionalities as middleware we can easily chain the request and return prematurely at each middleware if needed, for example if the user is not logged in whilst making the request. &lt;/p&gt;

&lt;p&gt;It might be chained as this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[LOG] -&amp;gt; [AUTH] -&amp;gt; [RETURN MSG]
[LOG] -&amp;gt; [AUTH] -&amp;gt; [RETURN USER]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;With the logic for &lt;strong&gt;LOG&lt;/strong&gt; and &lt;strong&gt;AUTH&lt;/strong&gt; separated, we only have to write the code and tests for it once. 🎉&lt;/p&gt;



&lt;p&gt;&lt;strong&gt;Middleware in Go&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In Go all of the network requests are fulfilling an interface called &lt;em&gt;&lt;a href="https://golang.org/pkg/net/http/#Handler" rel="noopener noreferrer"&gt;Handler&lt;/a&gt;&lt;/em&gt; in the &lt;em&gt;net/http&lt;/em&gt; package. For those unfamiliar with Go, a handler responds to a HTTP request and handles both reads from the request and writes to the response.&lt;/p&gt;

&lt;p&gt;Because Go comes with and expects this &lt;em&gt;Handler&lt;/em&gt; interface in it’s most crucial functions, it’s very easy and reliable to build packages around it and extend the interface with wrappers, such as middleware.&lt;/p&gt;

&lt;p&gt;A quick way to create a middleware would be to wrap the &lt;em&gt;net/http.Handler.ServeHTTP&lt;/em&gt; method;&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ServeHTTP(ResponseWriter, *Request)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;by adding a outer function that takes a &lt;em&gt;Handler&lt;/em&gt; as a parameter, as well as returning a &lt;em&gt;Handler&lt;/em&gt; which in this case takes the form of a &lt;em&gt;&lt;a href="https://golang.org/pkg/net/http/#HandlerFunc" rel="noopener noreferrer"&gt;HandlerFunc&lt;/a&gt;&lt;/em&gt;.&lt;/p&gt;


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



&lt;p&gt;The function above takes an argument of type &lt;em&gt;Handler&lt;/em&gt;, which is used to chain the request at the end of the method. Because we also return a &lt;em&gt;Handler&lt;/em&gt; type, we can chain the calls. It could look as such;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;firstMiddleware(secondMiddleware(lastHandler))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;From this simple method alone we can make a pretty good implementation of middleware. It might not be as robust as we would like, but it’s doable.&lt;/p&gt;

&lt;p&gt;Going forward I will use a package called &lt;a href="https://github.com/urfave/negroni" rel="noopener noreferrer"&gt;Negroni&lt;/a&gt; that makes this process a whole lot easier, although feel free to roll your own implementation. 👍&lt;/p&gt;

&lt;p&gt;Negroni wraps around your router of choice and provides functionality for middleware management. Such as a simpler, and more dynamic way of chaining middleware.&lt;/p&gt;



&lt;p&gt;&lt;strong&gt;Implementation — Wrapping the Handler&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In order to keep it as simple as possible, I’m planning on implementing a middleware that will log the execution time of a network request. The middleware will be built and executed with Negroni.&lt;/p&gt;

&lt;p&gt;Let’s start with creating our router and wrapping it in Negroni!&lt;/p&gt;


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



&lt;p&gt;As seen in the code sample above; we start out, on &lt;em&gt;line 12&lt;/em&gt;, with creating a new router with the &lt;em&gt;&lt;a href="https://github.com/gorilla/mux" rel="noopener noreferrer"&gt;gorilla/mux&lt;/a&gt;&lt;/em&gt; package, a popularly used package for router management. On the next few rows we register our endpoint, a &lt;em&gt;GET&lt;/em&gt; endpoint on the root path &lt;em&gt;/&lt;/em&gt;. So far, so good, and some of you will have seen this exact code before!&lt;/p&gt;

&lt;p&gt;On &lt;em&gt;line 18&lt;/em&gt; something new happens, we create a new instance of a Negroni handler, on &lt;em&gt;line 19&lt;/em&gt; we tell the instance to use the router that we previously created.&lt;/p&gt;

&lt;p&gt;Because Negroni fulfils the &lt;em&gt;&lt;a href="https://golang.org/pkg/net/http/#Handler" rel="noopener noreferrer"&gt;Handler&lt;/a&gt;&lt;/em&gt; interface, we can use it just as we would have used the router. Which we do on &lt;em&gt;line 21&lt;/em&gt;, we pass in the negroni handler in place of where we would normally pass in the &lt;em&gt;mux&lt;/em&gt; router. If you execute this code and call the endpoint you observe that it works as expected, eg. it logs &lt;em&gt;“Endpoint handler called”&lt;/em&gt; when calling:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;curl localhost:8080/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;Implementation — The birth of a Middleware&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Okay! So we have Negroni and an endpoint setup, let's continue with the middleware creation!&lt;/p&gt;

&lt;p&gt;As previously explained, a middleware is really just a Handler. So all we need to do is make a struct that fulfils the interface of a Handler. The twist here is that since we are using Negroni we have to implement their version of the Handler interface.&lt;/p&gt;

&lt;p&gt;As seen below it’s similar to the &lt;em&gt;net/http.Handler&lt;/em&gt; interface, except that it also has support for built in chaining with the &lt;em&gt;next&lt;/em&gt; parameter.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;type Handler interface {
    ServeHTTP(rw http.ResponseWriter, r *http.Request, next http.HandlerFunc)
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Let’s create a simple logger.&lt;/p&gt;


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



&lt;p&gt;The code snippet above shows how you could create a really simple middleware by fulfilling the &lt;em&gt;negroni.Handler&lt;/em&gt; interface. As seen, on &lt;em&gt;line 12&lt;/em&gt; we log some arbitrary information. On the next line we save the current timestamp to the variable &lt;em&gt;t&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Finally; on line 14 we continue the execution of the next handler&lt;/strong&gt;, which might be a another chained middleware or the final execution function. After that call has finished execution we log the total execution time.&lt;/p&gt;

&lt;p&gt;Let’s go ahead and add it to the router to see our execution time! ⏱&lt;/p&gt;


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


&lt;p&gt;As seen, the only change in the code here is on &lt;em&gt;line 20&lt;/em&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;n.Use(&amp;amp;mw.Logger{})
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;With that line of code we are telling Negroni to use the &lt;em&gt;Logger&lt;/em&gt; middleware that we created, the middleware are executed in the order they are inserted.&lt;/p&gt;

&lt;p&gt;If we execute this code and call the endpoint we end up with this log:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;The logger middleware is executing!
Endpoint handler called
Execution time: 25.146µs
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The first and third line is generated from the middleware, whilst the second line is generated in the function &lt;em&gt;endpointHandler&lt;/em&gt;; the final handler function for the endpoint. We’ve successfully made a middleware! 🙌&lt;/p&gt;



&lt;p&gt;Let’s play with the idea that we also had an Authentication middleware (AuthMW), the AuthMW would make sure that no unauthorised requests reaches the execution function. To add this to the chain we would simply do the following:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;n.Use(&amp;amp;mw.Logger{})
n.Use(&amp;amp;mw.Auth{})
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;With that change, we have built the first parts of a middleware chain. 👏&lt;/p&gt;

&lt;p&gt;The code above would execute the logger before continuing to the Auth middleware. In the same fashion you could build a chain of middleware for individual router paths, if we combine these two methods of chaining middleware we end up with some pretty powerful tools for building our routes and the code we want them to execute!&lt;/p&gt;

&lt;p&gt;The final code is available below.&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/johan-lejdung" rel="noopener noreferrer"&gt;
        johan-lejdung
      &lt;/a&gt; / &lt;a href="https://github.com/johan-lejdung/go-microservice-middleware-guide" rel="noopener noreferrer"&gt;
        go-microservice-middleware-guide
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Middleware example&lt;/h1&gt;

&lt;/div&gt;

&lt;p&gt;Run the code:&lt;/p&gt;

&lt;div class="snippet-clipboard-content notranslate position-relative overflow-auto"&gt;&lt;pre class="notranslate"&gt;&lt;code&gt;go run main.go
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Try calling the endpoint with&lt;/p&gt;
&lt;div class="snippet-clipboard-content notranslate position-relative overflow-auto"&gt;&lt;pre class="notranslate"&gt;&lt;code&gt;curl localhost:8080/ -v
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/johan-lejdung/go-microservice-middleware-guide" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;






&lt;p&gt;I hope that you found this interesting and that you learned something!&lt;/p&gt;

&lt;p&gt;If you did, you might find my previous article interesting as well. In it I go through how to build a REST API with a MySQL server connection in Go 🚀&lt;/p&gt;


&lt;div class="ltag__link"&gt;
  &lt;a href="/johanlejdung" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F209765%2Fb7371026-813d-40d7-8b38-afd5905b1b4d.jpg" alt="johanlejdung"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="/johanlejdung/a-mini-guide-build-a-rest-api-as-a-go-microservice-together-with-mysql-27m2" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;A mini-guide — Build a REST API as a Go microservice together with MySQL&lt;/h2&gt;
      &lt;h3&gt;Johan Lejdung ・ Aug 11 '19&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#go&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#beginners&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#sql&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#webdev&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;


&lt;p&gt;Furthermore, If you liked this article sharing it with friends or on Twitter is greatly appreciated!&lt;/p&gt;

&lt;p&gt;&lt;iframe class="tweet-embed" id="tweet-1186712393428209665-317" src="https://platform.twitter.com/embed/Tweet.html?id=1186712393428209665"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-1186712393428209665-317');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=1186712393428209665&amp;amp;theme=dark"
  }



&lt;/p&gt;

&lt;p&gt;Although this article took way longer than anticipated to write. It is my ambition to continue writing short guides like this, if you have any suggestions please comment below.&lt;/p&gt;

&lt;p&gt;Happy coding! &amp;lt;/⌨&amp;gt;️&lt;/p&gt;

</description>
      <category>go</category>
      <category>beginners</category>
      <category>middleware</category>
      <category>webdev</category>
    </item>
    <item>
      <title>A mini-guide — Build a REST API as a Go microservice together with MySQL</title>
      <dc:creator>Johan Lejdung</dc:creator>
      <pubDate>Sun, 11 Aug 2019 20:26:29 +0000</pubDate>
      <link>https://dev.to/johanlejdung/a-mini-guide-build-a-rest-api-as-a-go-microservice-together-with-mysql-27m2</link>
      <guid>https://dev.to/johanlejdung/a-mini-guide-build-a-rest-api-as-a-go-microservice-together-with-mysql-27m2</guid>
      <description>&lt;p&gt;I have recently found myself coding and deploying a lot of Go microservices, both at my day-job at Storytel and for my side-project &lt;a href="https://wiseer.io" rel="noopener noreferrer"&gt;Wiseer&lt;/a&gt;. In this mini-tutorial, I will create a simple REST-API with a MySQL database. The code for the complete project will be linked at the end of the article.&lt;/p&gt;

&lt;p&gt;If you haven’t already done so I recommend taking the &lt;a href="https://tour.golang.org/" rel="noopener noreferrer"&gt;Go Tour&lt;/a&gt; as a complementary to this article.&lt;/p&gt;

&lt;p&gt;Let’s dive in!&lt;/p&gt;




&lt;h1&gt;
  
  
  Setup the API
&lt;/h1&gt;

&lt;p&gt;One of the first things to do is to choose a routing package. Routing is what connects an URL to an executable function. The &lt;a href="https://github.com/gorilla/mux" rel="noopener noreferrer"&gt;mux package&lt;/a&gt; has served me well for &lt;em&gt;routing&lt;/em&gt;, but there are other alternatives as well, with no real difference in performance. Such as &lt;a href="https://github.com/julienschmidt/httprouter" rel="noopener noreferrer"&gt;httprouter&lt;/a&gt; and &lt;a href="https://github.com/go-chi/chi" rel="noopener noreferrer"&gt;chi&lt;/a&gt;. I will be using mux in this guide.&lt;/p&gt;

&lt;p&gt;For the sake of simplicity, we will create a single endpoint that prints out a message.&lt;/p&gt;


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


&lt;p&gt;The code above creates a &lt;em&gt;Router&lt;/em&gt;, associates a URL with an &lt;a href="https://golang.org/pkg/net/http/#HandlerFunc" rel="noopener noreferrer"&gt;handler function&lt;/a&gt; — postFunction in our case — and starts a server on port 8080 using that Router. &lt;/p&gt;

&lt;p&gt;Easy enough, huh? 🤠&lt;/p&gt;




&lt;h1&gt;
  
  
  Database connection
&lt;/h1&gt;

&lt;p&gt;Let's build on the code above by connecting it to a MySQL database. Go provides an &lt;a href="https://golang.org/pkg/database/sql/" rel="noopener noreferrer"&gt;interface&lt;/a&gt; for SQL databases but requires a driver. I’m using &lt;a href="https://medium.com/r/?url=https%3A%2F%2Fgithub.com%2Fgo-sql-driver%2Fmysql" rel="noopener noreferrer"&gt;go-sql-driver&lt;/a&gt; for this example.&lt;/p&gt;


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


&lt;p&gt;The code is placed in another package, called &lt;em&gt;db&lt;/em&gt;, and assumes there is a database running on &lt;em&gt;localhost:3306&lt;/em&gt; with a database called &lt;em&gt;demo&lt;/em&gt;. The returned database automatically handles a connection pool to the database.&lt;/p&gt;

&lt;p&gt;Let us update the &lt;em&gt;postFunction&lt;/em&gt; from the previous code-snippet, to use this database.&lt;/p&gt;


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


&lt;p&gt;That’s really it! It’s rather simple, but there are a few issues with the code above and a few nice-to-haves missing. This is where it gets a bit trickier, but don't jump ship just yet! ⚓️&lt;/p&gt;




&lt;h1&gt;
  
  
  Structs &amp;amp; Dependencies
&lt;/h1&gt;

&lt;p&gt;If you’ve examined the code above, you might have noticed that we are opening the database on each API-call; even though the opened database &lt;a href="https://golang.org/pkg/database/sql/#Open" rel="noopener noreferrer"&gt;is safe for concurrent use&lt;/a&gt;. We need some dependency management to make sure we only open the database once, for this, we want to use a &lt;a href="https://gobyexample.com/structs" rel="noopener noreferrer"&gt;struct&lt;/a&gt;.&lt;/p&gt;


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


&lt;p&gt;We start by creating a new package, called &lt;em&gt;app&lt;/em&gt;, to host our struct and it’s &lt;a href="https://gobyexample.com/methods" rel="noopener noreferrer"&gt;methods&lt;/a&gt;. Our &lt;em&gt;App&lt;/em&gt; struct has two fields; a &lt;em&gt;Router&lt;/em&gt; and a &lt;em&gt;Database&lt;/em&gt; accessed at &lt;em&gt;ln 17&lt;/em&gt; and &lt;em&gt;ln 24&lt;/em&gt;. We also set the returned status code manually at the end of the method at &lt;em&gt;ln 30&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;The main package and function also needs a few changes to make use of the new &lt;em&gt;App&lt;/em&gt; struct. We remove the &lt;em&gt;postFunction&lt;/em&gt; and &lt;em&gt;setupRouter&lt;/em&gt; functions from this package, since it’s now in the app package. We are left with:&lt;/p&gt;


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


&lt;p&gt;To make use of our new struct, we open a database and a new &lt;em&gt;Router&lt;/em&gt;. Then we insert both of them into the fields of our new &lt;em&gt;App&lt;/em&gt; struct.&lt;/p&gt;

&lt;p&gt;Congratulations! You now have a connection to your database that will be used concurrently across all of your incoming API-calls 🙌&lt;/p&gt;

&lt;p&gt;As a final step, we will add a &lt;em&gt;GET&lt;/em&gt;-Method to our router setup and return the data in &lt;em&gt;JSON&lt;/em&gt;. We start by adding a struct to fill our data with, and map the fields to &lt;em&gt;JSON&lt;/em&gt;.&lt;/p&gt;


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


&lt;p&gt;We follow that up with an expansion of the &lt;em&gt;app.go&lt;/em&gt; file, with a new method &lt;em&gt;getFunction&lt;/em&gt; that fetches and writes the data to the client response. The final file looks like this.&lt;/p&gt;


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





&lt;h1&gt;
  
  
  Database Migrations
&lt;/h1&gt;

&lt;p&gt;We are going to add a final addition to the project. When a database is tightly coupled with an application or service you can save yourself &lt;em&gt;unfathomable levels of headache&lt;/em&gt; by properly handling migrations of said database. We are going to use &lt;a href="https://github.com/golang-migrate/migrate" rel="noopener noreferrer"&gt;migrate&lt;/a&gt; for that, and expand our &lt;em&gt;db package&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;I'll go through the following, and admittedly long, gist below the embedded code.&lt;/p&gt;


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


&lt;p&gt;Right after the opening of the database, we add another function call to &lt;em&gt;migrateDatabase&lt;/em&gt; that will in turn; start the migration process.&lt;/p&gt;

&lt;p&gt;We will also add a MigrationLogger struct to handle the logging during the process, the code can be seen &lt;a href="https://github.com/johan-lejdung/go-microservice-api-guide/blob/master/rest-api/db/migrationlogger.go" rel="noopener noreferrer"&gt;here&lt;/a&gt; and it's usage on &lt;em&gt;ln 45&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;The migrations are executed from normal sql-queries. The migration files are read from the folder seen at &lt;em&gt;ln 37&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Each time the database is opened, all the unapplied database migrations will be applied. Thereby keeping the database up to date without any manuainterventionon.&lt;/p&gt;

&lt;p&gt;This coupled with a &lt;em&gt;docker-compose&lt;/em&gt; file - containing the database - makes development on multiple machines dead-simple.&lt;/p&gt;




&lt;h1&gt;
  
  
  Wrapping it up
&lt;/h1&gt;

&lt;p&gt;So you've made it all the way down here 👏 👏&lt;/p&gt;

&lt;p&gt;An undeployable microservice is of no use, therefore we will add a Dockerfile to package the application for easy distribution - &lt;em&gt;then I promise to let you go&lt;/em&gt;.&lt;/p&gt;


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


&lt;p&gt;The built image is a mere &lt;strong&gt;10MB&lt;/strong&gt;! 😱&lt;/p&gt;

&lt;p&gt;The code is available below.&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/johan-lejdung" rel="noopener noreferrer"&gt;
        johan-lejdung
      &lt;/a&gt; / &lt;a href="https://github.com/johan-lejdung/go-microservice-api-guide" rel="noopener noreferrer"&gt;
        go-microservice-api-guide
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;REST API&lt;/h1&gt;

&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Before cloning&lt;/h2&gt;

&lt;/div&gt;
&lt;p&gt;Read the accompanying article here: &lt;a href="https://medium.com/@johanlejdung/a-mini-guide-build-a-rest-api-as-a-go-microservice-together-with-mysql-fc203a6411c0" rel="nofollow noopener noreferrer"&gt;https://medium.com/@johanlejdung/a-mini-guide-build-a-rest-api-as-a-go-microservice-together-with-mysql-fc203a6411c0&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Change the module name if you are cloning it to a new location.&lt;/p&gt;
&lt;div class="snippet-clipboard-content notranslate position-relative overflow-auto"&gt;&lt;pre class="notranslate"&gt;&lt;code&gt;go mod init &amp;lt;your_module_name&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;If you are using a private repository make sure to set GOPRIVATE with:&lt;/p&gt;
&lt;div class="snippet-clipboard-content notranslate position-relative overflow-auto"&gt;&lt;pre class="notranslate"&gt;&lt;code&gt;go env -w GOPRIVATE=github.com/repoURL/private-repo
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Setup&lt;/h2&gt;

&lt;/div&gt;
&lt;p&gt;Included here are a &lt;code&gt;docker-compose&lt;/code&gt; file that can be used to spin up a MySQL database in docker for the porpose of running this code.&lt;/p&gt;
&lt;p&gt;Run the code:&lt;/p&gt;
&lt;div class="snippet-clipboard-content notranslate position-relative overflow-auto"&gt;&lt;pre class="notranslate"&gt;&lt;code&gt;go run main.go
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Try inserting a value with&lt;/p&gt;
&lt;div class="snippet-clipboard-content notranslate position-relative overflow-auto"&gt;&lt;pre class="notranslate"&gt;&lt;code&gt;curl -XPOST localhost:8080/endpoint -v
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Then fetching a value with&lt;/p&gt;
&lt;div class="snippet-clipboard-content notranslate position-relative overflow-auto"&gt;&lt;pre class="notranslate"&gt;&lt;code&gt;curl localhost:8080/endpoint/1 -v
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Further reading&lt;/h2&gt;

&lt;/div&gt;
&lt;p&gt;If you are interested in optimal folder structure, have a look at this &lt;a href="https://github.com/golang-standards/project-layout" rel="noopener noreferrer"&gt;github.com/golang-standards/project-layout&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;



&lt;/div&gt;
&lt;br&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/johan-lejdung/go-microservice-api-guide" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;
&lt;br&gt;





&lt;p&gt;I hope that you found this interesting and that you learned something! There are of course still things to improve upon, but that's where you and your creativity comes in 👍&lt;/p&gt;

&lt;p&gt;If you liked this article sharing it with friends or on Twitter is greatly appreciated!&lt;/p&gt;

&lt;p&gt;&lt;iframe class="tweet-embed" id="tweet-1160648900669267970-64" src="https://platform.twitter.com/embed/Tweet.html?id=1160648900669267970"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-1160648900669267970-64');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=1160648900669267970&amp;amp;theme=dark"
  }



&lt;/p&gt;

&lt;p&gt;I plan to cover more advanced topics in - hopefully shorter 😅 - articles. The topics I have thought of so far are; middleware usage, testing, dependency injection and service layers.&lt;/p&gt;

</description>
      <category>go</category>
      <category>beginners</category>
      <category>sql</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
