<?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: Eduardo Hitek</title>
    <description>The latest articles on DEV Community by Eduardo Hitek (@eduardohitek).</description>
    <link>https://dev.to/eduardohitek</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%2F11626%2Ffa3ed65b-d17e-4f54-839a-38b297c4b2d4.jpeg</url>
      <title>DEV Community: Eduardo Hitek</title>
      <link>https://dev.to/eduardohitek</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/eduardohitek"/>
    <language>en</language>
    <item>
      <title>Enabling Logs Query in Mongodb using Go</title>
      <dc:creator>Eduardo Hitek</dc:creator>
      <pubDate>Sat, 02 Sep 2023 12:33:00 +0000</pubDate>
      <link>https://dev.to/eduardohitek/enabling-logs-query-in-mongodb-using-go-15o8</link>
      <guid>https://dev.to/eduardohitek/enabling-logs-query-in-mongodb-using-go-15o8</guid>
      <description>&lt;p&gt;One way to debug an application is through logs. They can be used to identify issues, understand the execution flow, and also monitor the application's behavior. Among their types, database query logs are very useful for understanding what is happening with queries and other write operations. In this post, I will show how to enable MongoDB query logs in the official Go driver.&lt;/p&gt;

&lt;p&gt;By default, logs in the official MongoDB driver for Go are disabled. To enable them, you just need to implement your own CommandMonitor and set it in the ClientOptions configuration.&lt;/p&gt;

&lt;p&gt;Whenever I work with database connections, I like to create a struct that holds the necessary connection information. In this case, I'll create a struct called MongoConfig.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;MongoConfig&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;URL&lt;/span&gt;       &lt;span class="kt"&gt;string&lt;/span&gt;       &lt;span class="c"&gt;// MongoDB connection URL&lt;/span&gt;
    &lt;span class="n"&gt;AppName&lt;/span&gt;   &lt;span class="kt"&gt;string&lt;/span&gt;       &lt;span class="c"&gt;// Application name&lt;/span&gt;
    &lt;span class="n"&gt;DebugMode&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt;         &lt;span class="c"&gt;// Flag to enable debug logs&lt;/span&gt;
    &lt;span class="n"&gt;Log&lt;/span&gt;       &lt;span class="n"&gt;slog&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Logger&lt;/span&gt;  &lt;span class="c"&gt;// Logger to be used&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After that, I implement a createMongoClient function that takes this configuration struct and returns a *mongo.Client. The advantage of passing configurations via a struct is that if you want to add other parameters like ConnectionTimeout or MaxPoolSize, for example, you don't need to change the function's signature.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;createMongoClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cfg&lt;/span&gt; &lt;span class="n"&gt;MongoConfig&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;mongo&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Client&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;clientOptions&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Client&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ApplyURI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cfg&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;URL&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;clientOptions&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SetAppName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cfg&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AppName&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;cfg&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DebugMode&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="c"&gt;// Verifico se a flag de debug está habilitada&lt;/span&gt;
        &lt;span class="n"&gt;monitor&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;event&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CommandMonitor&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;Started&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CommandStartedEvent&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CommandName&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="s"&gt;"endSessions"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="c"&gt;// Ignoro os comandos de finalização de sessão&lt;/span&gt;
                    &lt;span class="n"&gt;cfg&lt;/span&gt;&lt;span class="o"&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;Info&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Command&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
                &lt;span class="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;clientOptions&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SetMonitor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;monitor&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;client&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;mongo&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Connect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Background&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;clientOptions&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Afterward, I use the function to create the MongoDB client and perform operations in my application.&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;mongoCfg&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;MongoConfig&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;URL&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;       &lt;span class="s"&gt;"mongodb://localhost:27017"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;AppName&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;   &lt;span class="s"&gt;"MongoDB with query log"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;DebugMode&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="no"&gt;true&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="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;slog&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Default&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;client&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;createMongoClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;mongoCfg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Fatal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Examples of logs for some operations:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;PING
2023/09/02 08:48:09 INFO {"ping": {"$numberInt":"1"},"lsid": {"id": {"$binary":{"base64":"HBu0mDZaRHaNx0TPpBcaeg==","subType":"04"}}},"$db": "admin"}

INSERT
2023/09/02 09:04:43 INFO {"insert": "users","ordered": true,"lsid": {"id": {"$binary":{"base64":"ZIZW5N5OR+ympGFggFu6uA==","subType":"04"}}},"$db": "example-mongo","documents": [{"_id": {"$oid":"64f324db99a1dac5fdc37251"},"name": "Eduardo","alias": "eduardohitek","site": "https://eduardohitek.dev"}]}

FIND
2023/09/02 09:05:59 INFO {"find": "users","filter": {"alias": "eduardohitek"},"lsid": {"id": {"$binary":{"base64":"+ji9+sJIRVC0HsawBmTAPw==","subType":"04"}}},"$db": "example-mongo"}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here is a &lt;strong&gt;&lt;a href="https://gist.github.com/eduardohitek/000326c951ffce59bb03339b41e4d601"&gt;gist&lt;/a&gt;&lt;/strong&gt; with the code used in the post.&lt;/p&gt;

</description>
      <category>mongodb</category>
      <category>go</category>
    </item>
    <item>
      <title>List of apps I use every day - Version 2023</title>
      <dc:creator>Eduardo Hitek</dc:creator>
      <pubDate>Tue, 20 Jun 2023 17:23:00 +0000</pubDate>
      <link>https://dev.to/eduardohitek/list-of-apps-i-use-every-day-version-2023-a88</link>
      <guid>https://dev.to/eduardohitek/list-of-apps-i-use-every-day-version-2023-a88</guid>
      <description>&lt;p&gt;I enjoy reading posts about the tools/apps people use in their daily lives, whether for work or personal use. I always end up discovering new tools or functionalities that I wasn't aware of. That's why I decided to create a post about the apps I use every day. The idea is to update this post every year to see how things change.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://iterm2.com/downloads/stable/latest"&gt;&lt;strong&gt;iTerm2&lt;/strong&gt;&lt;/a&gt;: It has been my terminal of choice for macOS for years and continues to serve me well to this day. However, I have been following the development of &lt;a href="https://raphamorim.io/rio/"&gt;Rio&lt;/a&gt;, an alternative being developed by &lt;a href="https://twitter.com/raphamorims"&gt;@raphamorims&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://fishshell.com/"&gt;&lt;strong&gt;fish&lt;/strong&gt;&lt;/a&gt;: A very fast shell with various customization options to streamline daily commands. I discovered it through this &lt;a href="https://carlosbecker.com/posts/fish/"&gt;post&lt;/a&gt; by &lt;a href="https://twitter.com/caarlos0"&gt;@caarlos0&lt;/a&gt;, where he provides more details about performance and the differences between fish and zsh. Additionally, I use some CLI utilities like &lt;a href="https://github.com/dandavison/delta"&gt;delta&lt;/a&gt;, &lt;a href="https://the.exa.website/"&gt;exa&lt;/a&gt;, and &lt;a href="https://github.com/BurntSushi/ripgrep"&gt;ripgrep&lt;/a&gt;. Here's my &lt;a href="https://github.com/eduardohitek/dotfiles.fish"&gt;dotfiles&lt;/a&gt; for fish.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://arc.net/"&gt;&lt;strong&gt;Arc&lt;/strong&gt;&lt;/a&gt;: The new favorite when it comes to browsers. It has a contextual tab organization feature based on your usage, which helps separate work-related and personal items. It's worth taking a look. If you need an invitation, just let me know.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://shottr.cc/"&gt;&lt;strong&gt;Shottr&lt;/strong&gt;&lt;/a&gt;: A tool for taking screenshots and sharing them with others. It offers more functionality than the native macOS tool and is much lighter than &lt;a href="https://evernote.com/products/skitch"&gt;Skitch&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://rectangleapp.com/"&gt;&lt;strong&gt;Rectangle&lt;/strong&gt;&lt;/a&gt;: A handy tool for organizing windows on macOS. In my case, as I use two monitors, it's very helpful when I need to move apps from one screen to another or when I want to arrange windows side by side. It offers various shortcut options and configurations to suit your window management needs.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.alfredapp.com/"&gt;&lt;strong&gt;Alfred&lt;/strong&gt;&lt;/a&gt;: A well-known replacement for the native Spotlight. It's a productivity tool that I use to open apps, search for files, execute commands, etc. The free version is already quite useful, but the paid version brings more functionality and integrations with other apps.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://apps.apple.com/br/app/copyclip-clipboard-history/id595191960?mt=12"&gt;&lt;strong&gt;CopyClip&lt;/strong&gt;&lt;/a&gt;: A lifesaver with clipboard history. I use it a lot for copying and pasting texts that I need to use in multiple places. You can define how many items you want it to store in the history and set shortcuts for frequently used items.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://cron.com/download/macos"&gt;&lt;strong&gt;Cron&lt;/strong&gt;&lt;/a&gt;: An alternative to the native macOS calendar application. It has a cleaner and simpler interface to use. There is also an iOS version that syncs with macOS.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.notion.so/"&gt;&lt;strong&gt;Notion&lt;/strong&gt;&lt;/a&gt;: A well-known tool responsible for various courses on Udemy :) I use it to organize my studies, take notes and create my &lt;a href="https://eltonminetto.dev/post/2022-04-14-brag-document/"&gt;bragdoc&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://zed.dev/"&gt;&lt;strong&gt;Zed&lt;/strong&gt;&lt;/a&gt;: A text editor that I am currently testing and using to write this post. It provides a more minimalist and clean approach without relying on many extensions, with built-in features such as Github Copilot, LSP, and live collaboration.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://eduardohitek.dev/posts-en/2023-06-20-apps-that-i-use/"&gt;View original post&lt;/a&gt;&lt;/p&gt;

</description>
      <category>fish</category>
      <category>zed</category>
      <category>arc</category>
      <category>discuss</category>
    </item>
    <item>
      <title>Highlights in a Technical Interview for Junior Candidates</title>
      <dc:creator>Eduardo Hitek</dc:creator>
      <pubDate>Thu, 15 Jun 2023 07:11:00 +0000</pubDate>
      <link>https://dev.to/eduardohitek/highlights-in-a-technical-interview-for-junior-candidates-1lfp</link>
      <guid>https://dev.to/eduardohitek/highlights-in-a-technical-interview-for-junior-candidates-1lfp</guid>
      <description>&lt;h2&gt;
  
  
  Highlights in a Technical Interview for Junior Candidates
&lt;/h2&gt;

&lt;p&gt;Recently, someone who is seeking their first opportunity in the development field asked me for advice on what to study or what certifications to obtain to stand out in a job interview. I didn't respond immediately and took some time to think, as the landscape has changed significantly since I was a Junior Developer.&lt;/p&gt;

&lt;p&gt;So, I came up with a list of 7 topics that I believe make a difference for someone at this professional stage and would catch my attention during an interview process.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Disclaimer&lt;/em&gt;&lt;/strong&gt;: &lt;em&gt;The idea is not for the person to delve deep and become an expert in these items; that can happen later with work experience. The intention is to have a basic understanding and be able to discuss the topics in an interview.&lt;/em&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Docker&lt;/strong&gt;: It's quite rare to have no contact with container solutions in the field, so it's interesting to have an understanding of what Docker is, how to create, run, stop, and check logs of a locally running &lt;a href="https://www.docker.com/products/docker-desktop/"&gt;Docker&lt;/a&gt; container.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Git&lt;/strong&gt;: After surviving &lt;a href="https://en.wikipedia.org/wiki/Concurrent_Versions_System"&gt;CVS&lt;/a&gt; and &lt;a href="https://en.wikipedia.org/wiki/Apache_Subversion"&gt;SVN&lt;/a&gt;, I don't see any other version control solution taking over Git in our day-to-day work. Therefore, understanding concepts like branches, merge vs. rebase, and how to recover from errors is a differentiating factor.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CI/CD&lt;/strong&gt;: Here, it's not about knowing how to set up a workflow in Github Actions, but rather understanding the meanings of the acronyms &lt;a href="https://www.atlassian.com/continuous-delivery"&gt;CI/CD&lt;/a&gt; and the value they bring to the quality of the final code and time saved through automation.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Testing&lt;/strong&gt;: Even if you haven't gone beyond unit or integration testing, it's good to have an understanding of other types of &lt;a href="https://www.atlassian.com/continuous-delivery/software-testing"&gt;tests&lt;/a&gt; and in which scenarios they are important.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Databases&lt;/strong&gt;: Many people only get the chance to work with relational databases (&lt;a href="https://www.mysql.com/"&gt;MySQL&lt;/a&gt; or &lt;a href="https://www.postgresql.org/"&gt;Postgres&lt;/a&gt;), so it's interesting to explore NoSQL solutions (&lt;a href="https://www.mongodb.com/"&gt;MongoDB&lt;/a&gt;, &lt;a href="https://cassandra.apache.org/"&gt;Cassandra&lt;/a&gt;, etc.). It's a plus to know in which scenarios each approach can be more suitable.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Agile Methodologies&lt;/strong&gt;: Most likely, you will join a team that uses a variant of &lt;a href="https://www.atlassian.com/agile/scrum"&gt;Scrum&lt;/a&gt; or &lt;a href="https://www.totvs.com/blog/negocios/kanban/"&gt;Kanban&lt;/a&gt; (or perhaps both), so it's valuable to already know how they work and understand the rituals of these methodologies.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;REST API Patterns&lt;/strong&gt;: Whether working on the front-end or back-end, there's a high chance that you'll be involved in synchronous communication using &lt;a href="https://www.redhat.com/en/topics/api/what-is-a-rest-api"&gt;REST APIs&lt;/a&gt;. It's worthwhile to understand the methods, URL best practices, code best practices, error messages, and more.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;As I mentioned earlier, the intention is not for you to become an expert in the items above, nor to know them all. However, I guarantee that having a basic understanding can make a considerable difference during a technical interview.&lt;/p&gt;

&lt;p&gt;Do you agree with the points above? Please leave a comment with your thoughts or if you believe any items are missing from this list.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://eduardohitek.dev/posts-en/2023-06-13-highlights-technical-interview-junior-candidates/"&gt;View original post&lt;/a&gt;&lt;/p&gt;

</description>
      <category>interview</category>
      <category>docker</category>
      <category>cicd</category>
      <category>tips</category>
    </item>
    <item>
      <title>Performing Benchmark Tests in Go</title>
      <dc:creator>Eduardo Hitek</dc:creator>
      <pubDate>Sun, 01 Aug 2021 00:13:21 +0000</pubDate>
      <link>https://dev.to/eduardohitek/performing-benchmark-tests-in-go-29p2</link>
      <guid>https://dev.to/eduardohitek/performing-benchmark-tests-in-go-29p2</guid>
      <description>&lt;p&gt;Benchmark testing in programming is the act of efficiently comparing performance between algorithms in order to choose which approach to follow in certain scenarios. We can also apply when deciding which external libraries or frameworks to use, in addition to evaluating if any refactoring will bring harm to our code.&lt;/p&gt;

&lt;p&gt;The Go language already has tools for these types of tests by default, making the experience more user-friendly and without the need for external tools.&lt;/p&gt;

&lt;p&gt;Let's see how to verify this in practice.&lt;/p&gt;

&lt;h3&gt;
  
  
  Analyzing Palindromic Verification Performance
&lt;/h3&gt;

&lt;p&gt;Palindrome is a word or group of words that have linear symmetry, that is, they remain the same when read backwards. A more common example is the word &lt;code&gt;level&lt;/code&gt; or &lt;code&gt;anna&lt;/code&gt; where the reading order does not change the meaning of the word. We can also obtain this effect by combining a few words, forming simple sentences like: &lt;code&gt;never odd or even&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;It is quite common in job interviews that you are faced with the challenge of writing an algorithm to check whether a phrase or word is palindrome or not.&lt;/p&gt;

&lt;p&gt;For examples I used 3 different algorithms to analyze which will have the best performance:&lt;/p&gt;

&lt;p&gt;1) &lt;strong&gt;PalindromeReverse&lt;/strong&gt;: receives a string, reverses it and checks if the 2 strings are equal.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;func reverse(s string) string {
   runes := []rune(s)
   for i, j := 0, len(runes)-1; i&amp;lt;j; i, j = i+1, j-1 {
       runes[i], runes[j] = runes[j], runes[i]
   }
   return string(runes)
}

func palindromeReverse(str string) bool {
   strReversed := reverse(str)
   return strReversed == str
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;2) &lt;strong&gt;PalindromeFromEnd&lt;/strong&gt;: cycles through the string comparing the 1st word with the last and so on.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;func palindromeFromEnd(str string) bool {
   runes := []rune(str)
   length := len(runes)
   for i := 0; i &amp;lt; length; i++ {
       if runes[i] != runes[length-1-i] {
           return false
       }
   }
   return true
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;1) &lt;strong&gt;palindromeFromMiddle&lt;/strong&gt;: runs from the middle characters to the beginning/end of the string.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;func palindromeFromMiddle(str string) bool {
   runes := []rune(str)
   length := len(runes)
   middleI, middleJ := (length/2)-1, (length/2)+1
   if length%2 == 0 {
       middleJ -= 1
   }

   for i, j := middleI, middleJ; i &amp;gt;= 0; i, j = i-1, j+1 {
       if runes[i] != runes[j] {
           return false
       }
   }
   return true
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With the functions created, now we need to write the Benchmark Tests functions.&lt;/p&gt;

&lt;h3&gt;
  
  
  Benchmark Tests
&lt;/h3&gt;

&lt;p&gt;In our example, let's create the test file &lt;code&gt;main_test.go&lt;/code&gt; and within it create the following test functions:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;func BenchmarkPalindromeFromMiddle_Banana(b *testing.B) {
   for n := 0; n&amp;lt;b.N; n++ {
       palindromeFromMiddle("banana")
   }
}
func BenchmarkPalindromeReverse_Banana(b *testing.B) {
   for n := 0; n&amp;lt;b.N; n++ {
       palindromeReverse("banana")
   }
}
func BenchmarkPalindromeFromEnd_Banana(b *testing.B) {
   for n := 0; n&amp;lt;b.N; n++ {
       palindromeFromEnd("banana")
   }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here we are asking Go to run each of the functions with the &lt;code&gt;banana&lt;/code&gt; string. Next step is to run the following command in the terminal: &lt;code&gt;go test -bench=. -benchtime=1s&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;~/dev/eduardohitek/go-benchmark-example main*
❯ go test -bench=. -benchtime=1s
goos: darwin
goarch: amd64
pkg: github.com/eduardohitek/go-benchmark-example
cpu: Intel(R) Core(TM) i7-8750H CPU @ 2.20GHz
BenchmarkPalindromeFromMiddle_Banana-12 69054604 16.36 ns/op
BenchmarkPalindromeReverse_Banana-12 16145308 69.83 ns/op
BenchmarkPalindromeFromEnd_Banana-12 91725068 15.84 ns/op
PASS
ok github.com/eduardohitek/go-benchmark-example 4.563s
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Following the argument we informed, each benchmark function is executed for 1 second and we have 2 pieces of information for each: Number of executions and average time of each execution. For this example of a non-palindromic word, and when the difference was between the 1st and the last letter, the &lt;strong&gt;BenchmarkPalindromeFromEnd_Banana&lt;/strong&gt; was more performant because it had a lower average time per operation.&lt;/p&gt;

&lt;p&gt;In the next example we use a word major palindrome (&lt;em&gt;nomelgibsonisacasinosbiglemon&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;~/dev/eduardohitek/go-benchmark-example main*
❯ go test -bench=. -benchtime=1s
goos: darwin
goarch: amd64
pkg: github.com/eduardohitek/go-benchmark-example
cpu: Intel(R) Core(TM) i7-8750H CPU @ 2.20GHz
BenchmarkPalindromeFromMiddle_nomelgibsonisacasinosbiglemon-12 18193920 56.29 ns/op
BenchmarkPalindromeReverse_nomelgibsonisacasinosbiglemon-12 4255890 272.6 ns/op
BenchmarkPalindromeFromEnd_nomelgibsonisacasinosbiglemon-12 16961797 63.68 ns/op
PASS
ok github.com/eduardohitek/go-benchmark-example 5.078s

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

&lt;/div&gt;



&lt;p&gt;In this example the &lt;strong&gt;BenchmarkPalindromeFromMiddle&lt;/strong&gt; came out ahead. The last test uses a much longer string (+800 characters) and we confirm which function does better in this scenario:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;~/dev/eduardohitek/go-benchmark-example main*
❯ go test -bench=. -benchtime=1s
goos: darwin
goarch: amd64
pkg: github.com/eduardohitek/go-benchmark-example
cpu: Intel(R) Core(TM) i7-8750H CPU @ 2.20GHz
BenchmarkPalindromeFromMiddle_longstring-12 672807 1774 ns/op
BenchmarkPalindromeReverse_longstring-12 141945 7784 ns/op
BenchmarkPalindromeFromEnd_longstring-12 524437 2121 ns/op
PASS
ok github.com/eduardohitek/go-benchmark-example 5.006s
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So we could see how easy it is to perform this type of tests to assess the changes and performance of algorithms in Go applications.&lt;/p&gt;

&lt;p&gt;All source code for the examples is found &lt;a href="https://github.com/eduardohitek/go-benchmark-example"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Originally posted on my &lt;a href="https://eduardohitek.dev/posts-en/benchmark-in-go/"&gt;website&lt;/a&gt;&lt;/p&gt;

</description>
      <category>go</category>
      <category>tests</category>
      <category>benchmark</category>
    </item>
    <item>
      <title>Installing Portainer for managing Docker instances</title>
      <dc:creator>Eduardo Hitek</dc:creator>
      <pubDate>Sat, 17 Jul 2021 13:50:32 +0000</pubDate>
      <link>https://dev.to/eduardohitek/installing-portainer-for-managing-docker-instances-5i3</link>
      <guid>https://dev.to/eduardohitek/installing-portainer-for-managing-docker-instances-5i3</guid>
      <description>&lt;p&gt;&lt;a href="https://www.portainer.io/products/community-edition"&gt;Portainer&lt;/a&gt; is an Open Source application for managing Docker on local machines or servers.&lt;br&gt;
Through its graphical interface it is possible to view and edit your Containers, Images, Volumes and so on. And its installation is very easy as it is distributed as a Docker image.&lt;/p&gt;

&lt;p&gt;Just perform the following steps:&lt;/p&gt;

&lt;p&gt;1) Create a &lt;code&gt;volume&lt;/code&gt; to persist your settings:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker volume create portainer_data
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;1) Run the docker command to create the container and inform some initial configuration parameters:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker run -d -p 9000:9000 --name=portainer --restart=always -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data portainer/portainer-ce
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With this command we are telling Docker to run this container in the background mode, export port 9000, set the name to &lt;code&gt;portainer&lt;/code&gt;, set the restart policy to always restart and link the container volumes to local volumes on your machine.&lt;/p&gt;

&lt;p&gt;After executing the command, just access &lt;a href="http://localhost:9000"&gt;http://localhost:9000&lt;/a&gt; and set the admin password.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--2uIFFbql--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://eduardohitek.com/images/portainer/1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--2uIFFbql--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://eduardohitek.com/images/portainer/1.png" alt="Set Portainer Access Password"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The next step is to point which environment you want to manage, in my case I will select the local docker instance.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--1jnO4uKz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://eduardohitek.com/images/portainer/2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--1jnO4uKz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://eduardohitek.com/images/portainer/2.png" alt="Select environment for management"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And that's it, you'll have the lists of active containers, their status and possible available actions.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--AnxKaD8I--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://eduardohitek.com/images/portainer/3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--AnxKaD8I--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://eduardohitek.com/images/portainer/3.png" alt="List of containers"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>docker</category>
      <category>portainer</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Microservices: HTTP Requests vs Messaging</title>
      <dc:creator>Eduardo Hitek</dc:creator>
      <pubDate>Tue, 18 Jun 2019 19:57:49 +0000</pubDate>
      <link>https://dev.to/eduardohitek/microservices-http-requests-vs-messaging-1eaf</link>
      <guid>https://dev.to/eduardohitek/microservices-http-requests-vs-messaging-1eaf</guid>
      <description>&lt;h2&gt;
  
  
  I'm currently designing a solution using Microservices and saw both implementations (HTTP Requests and Messaging) for communication between them. Considering that theses microservices will run on the same network, in what scenarios do you recommend each one of them?
&lt;/h2&gt;

</description>
      <category>discuss</category>
      <category>microservices</category>
      <category>http</category>
      <category>rest</category>
    </item>
    <item>
      <title>MongoDB Golang Driver Tutorial</title>
      <dc:creator>Eduardo Hitek</dc:creator>
      <pubDate>Sun, 16 Jun 2019 16:26:05 +0000</pubDate>
      <link>https://dev.to/eduardohitek/mongodb-golang-driver-tutorial-49e5</link>
      <guid>https://dev.to/eduardohitek/mongodb-golang-driver-tutorial-49e5</guid>
      <description>&lt;p&gt;After years relying on Community drivers like &lt;a href="https://github.com/go-mgo/mgo"&gt;mgo&lt;/a&gt; and &lt;a href="https://github.com/globalsign/mgo"&gt;globalsign/mgo&lt;/a&gt;, last year MongoDB &lt;a href="https://engineering.mongodb.com/post/considering-the-community-effects-of-introducing-an-official-golang-mongodb-driver"&gt;announced&lt;/a&gt; they were building it’s own solution. Last March they &lt;a href="https://www.mongodb.com/blog/post/official-mongodb-go-driver-now-ga-and-ready-for-production"&gt;released&lt;/a&gt; the version 1.0.0, so let’s see how to make some normal operations using the Oficial driver.&lt;/p&gt;

&lt;p&gt;First of all, you need to download the driver using go get.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;go.mongodb.org/mongo-driver/mongo
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Assuming your MongoDB installation is using the default setting, your method should be like this:&lt;/p&gt;

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

import (
    "context"
    "log"

    "go.mongodb.org/mongo-driver/mongo"
    "go.mongodb.org/mongo-driver/mongo/options"
    "go.mongodb.org/mongo-driver/mongo/readpref"
)

func GetClient() *mongo.Client {
    clientOptions := options.Client().ApplyURI("mongodb://localhost:27017")
    client, err := mongo.NewClient(clientOptions)
    if err != nil {
        log.Fatal(err)
    }
    err = client.Connect(context.Background())
    if err != nil {
        log.Fatal(err)
    }
    return client
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;To test the connection to the mongo, we can call a function called Ping, and check if return any error. Otherwise, out connection was successful.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;func main() {
    c := GetClient()
    err := c.Ping(context.Background(), readpref.Primary())
    if err != nil {
        log.Fatal("Couldn't connect to the database", err)
    } else {
        log.Println("Connected!")
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Now for the next examples I created a database called &lt;code&gt;civilact&lt;/code&gt; and a collection &lt;code&gt;heroes&lt;/code&gt; and add the followings documents:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{ 
    "_id" : ObjectId("5d0574824d9f7ff15e989171"), 
    "name" : "Tony Stark", 
    "alias" : "Iron Man", 
    "signed" : true
}
{ 
    "_id" : ObjectId("5d0574d74d9f7ff15e989172"), 
    "name" : "Steve Rodgers", 
    "alias" : "Captain America", 
    "signed" : false
}
{ 
    "_id" : ObjectId("5d0574e94d9f7ff15e989173"), 
    "name" : "Vision", 
    "alias" : "Vision", 
    "signed" : true
}
{ 
    "_id" : ObjectId("5d0575344d9f7ff15e989174"), 
    "name" : "Clint Barton", 
    "alias" : "Hawkeye", 
    "signed" : false
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;To work with these documents, would be better if we create a struct that represents all the Fields and their json names.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;type Hero struct {
    Name   string `json:"name"`
    Alias  string `json:"alias"`
    Signed bool   `json:"signed"`
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Now let's create a Method that will return all Heroes expecting 2 parameters: MongoDB Client and a bson.M that represents a filter. Is this filter is empty, the method will return all documents.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import (
    "context"
    "log"

    "go.mongodb.org/mongo-driver/bson"
    "go.mongodb.org/mongo-driver/mongo"
    "go.mongodb.org/mongo-driver/mongo/options"
    "go.mongodb.org/mongo-driver/mongo/readpref"
)

func ReturnAllHeroes(client *mongo.Client, filter bson.M) []*Hero {
    var heroes []*Hero
    collection := client.Database("civilact").Collection("heroes")
    cur, err := collection.Find(context.TODO(), filter)
    if err != nil {
        log.Fatal("Error on Finding all the documents", err)
    }
    for cur.Next(context.TODO()) {
        var hero Hero
        err = cur.Decode(&amp;amp;hero)
        if err != nil {
            log.Fatal("Error on Decoding the document", err)
        }
        heroes = append(heroes, &amp;amp;hero)
    }
    return heroes
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The breakdown is:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create a &lt;code&gt;collection&lt;/code&gt; that represents the collection in the database;&lt;/li&gt;
&lt;li&gt;Ask the &lt;code&gt;collection&lt;/code&gt; to return a cursor of with the elements based oh the filter (in this case the filter is empty, so will return all elements);&lt;/li&gt;
&lt;li&gt;Iterate this cursor and Decode each document to a Hero type;&lt;/li&gt;
&lt;li&gt;Append the Hero decoded in the &lt;code&gt;heroes&lt;/code&gt; array.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If we run inside the main function, our return will be:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;heroes := ReturnAllHeroes(c, bson.M{})
for _, hero := range heroes {
    log.Println(hero.Name, hero.Alias, hero.Signed)
}

2019/06/15 21:07:00 Tony Stark Iron Man true
2019/06/15 21:07:00 Steve Rodgers Captain America false
2019/06/15 21:07:00 Vision Vision true
2019/06/15 21:07:00 Clint Barton Hawkeye false
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;To retrieve just the Heroes whom signed the &lt;a href="https://marvelcinematicuniverse.fandom.com/wiki/Sokovia_Accords"&gt;Sokovia Accords&lt;/a&gt;, we just need to change the filter.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;heroes := ReturnAllHeroes(c, bson.M{"signed": true})

2019/06/15 21:18:04 Tony Stark Iron Man true
2019/06/15 21:18:04 Vision Vision true
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;To retrieve just one Hero, our new method will be like this:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;func ReturnOneHero(client *mongo.Client, filter bson.M) Hero {
    var hero Hero
    collection := client.Database("civilact").Collection("heroes")
    documentReturned := collection.FindOne(context.TODO(), filter)
    documentReturned.Decode(&amp;amp;hero)
    return hero
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The call will be:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    hero := ReturnOneHero(c, bson.M{"name": "Vision"})
    log.Println(hero.Name, hero.Alias, hero.Signed)

    2019/06/15 22:55:44 Vision Vision true
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Now, to increase our collection of Heroes and insert, for example Doctor Strange: The new method will be like this:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;func InsertNewHero(client *mongo.Client, hero Hero) interface{} {
    collection := client.Database("civilact").Collection("heroes")
    insertResult, err := collection.InsertOne(context.TODO(), hero)
    if err != nil {
        log.Fatalln("Error on inserting new Hero", err)
    }
    return insertResult.InsertedID
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;That's how we method will be used and checked by our previous method &lt;code&gt;ReturnOneHero&lt;/code&gt;:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;hero = Hero{Name: "Stephen Strange", Alias: "Doctor Strange", Signed: true}
insertedID := InsertNewHero(c, hero)
log.Println(insertedID)
hero = ReturnOneHero(c, bson.M{"alias": "Doctor Strange"})
log.Println(hero.Name, hero.Alias, hero.Signed)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Great! We added a Sorcerer Supreme in our Heroes collection, but what if he didn't like and asked us to remove him from it? Well, that's why we need a &lt;code&gt;RemoveOneHero&lt;/code&gt; method.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;func RemoveOneHero(client *mongo.Client, filter bson.M) int64 {
    collection := client.Database("civilact").Collection("heroes")
    deleteResult, err := collection.DeleteOne(context.TODO(), filter)
    if err != nil {
        log.Fatal("Error on deleting one Hero", err)
    }
    return deleteResult.DeletedCount
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;And that's how we check:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;heroesRemoved := RemoveOneHero(c, bson.M{"alias": "Doctor Strange"})
log.Println("Heroes removed count:", heroesRemove
hero = ReturnOneHero(c, bson.M{"alias": "Doctor Strange"})
log.Println("Is Hero empty?", hero == Hero{ })
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;For last, let's imagine that Hawkeye changed his mind and now wants to sign the Accords. So let's make de &lt;code&gt;UpdateHero&lt;/code&gt; method.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;func UpdateHero(client *mongo.Client, updatedData bson.M, filter bson.M) int64 {
    collection := client.Database("civilact").Collection("heroes")
    atualizacao := bson.D{ {Key: "$set", Value: updatedData} }
    updatedResult, err := collection.UpdateOne(context.TODO(), filter, atualizacao)
    if err != nil {
        log.Fatal("Error on updating one Hero", err)
    }
    return updatedResult.ModifiedCount
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;That's it! The regular CRUD Operation was covered and our Heroes can decide their fate.&lt;br&gt;
All the code for these examples is available &lt;a href="http://github.com/eduardohitek/mongodb-go-example"&gt;here&lt;/a&gt; and this tutorial was also posted at my &lt;a href="http://blog.eduardohitek.com"&gt;blog&lt;/a&gt;. Here is the Driver's oficial &lt;a href="https://github.com/mongodb/mongo-go-driver"&gt;repo&lt;/a&gt; and oficial &lt;a href="https://godoc.org/go.mongodb.org/mongo-driver/mongo"&gt;docs&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Feel free to get in touch for any question, suggestion or mistake that i made.&lt;/p&gt;

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