<?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: Héctor Vela</title>
    <description>The latest articles on DEV Community by Héctor Vela (@makko).</description>
    <link>https://dev.to/makko</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%2F63398%2Fc723d6fd-634b-4324-83cb-c18474ab6bbf.png</url>
      <title>DEV Community: Héctor Vela</title>
      <link>https://dev.to/makko</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/makko"/>
    <language>en</language>
    <item>
      <title>Seeing the Big Picture: A Key Skill for Software Engineers</title>
      <dc:creator>Héctor Vela</dc:creator>
      <pubDate>Fri, 17 Nov 2023 22:00:13 +0000</pubDate>
      <link>https://dev.to/makko/seeing-the-big-picture-a-key-skill-for-software-engineers-2ipf</link>
      <guid>https://dev.to/makko/seeing-the-big-picture-a-key-skill-for-software-engineers-2ipf</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--6c7H9Ba9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2ef1ms6d3gc0trfgu75q.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--6c7H9Ba9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2ef1ms6d3gc0trfgu75q.jpg" alt="Image description" width="545" height="588"&gt;&lt;/a&gt;&lt;br&gt;
Have you heard the expression "missing the forest for the trees" ? It's a classical example of not being able to see the big picture, to put all your attention and focus on just a small part of a larger situation. &lt;em&gt;Big picture thinking refers to a thinking strategy that focuses on the entirety of a concept or idea instead of on each individual detail&lt;/em&gt;1.&lt;/p&gt;

&lt;p&gt;Being able to appreciate the big picture is an essential skill for any professional, but I think it is particularly important for IT consultants. We, as software engineers, quality engineers, project managers, SREs and all other IT professions, are usually part of a complex ecosystem of technologies, processes and business rules and decisions. &lt;strong&gt;Nobody is an island&lt;/strong&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Once, in a project, a seemingly simple change needed to be implemented. The task involved adding a "tag" to the objects within a system. This "tag" was obtained from another system. The change itself was straightforward: adding an extra field to the object, making a call to the service, and storing the data in the object. The ticket was rated at 1 story point.&lt;/p&gt;

&lt;p&gt;The tagging system was maintained by a team in a different time zone, and it took a couple of days to adjust the integration. Subsequently, validating and testing the change took a couple more days. Thus, what was initially a 1-point change ended up taking almost two weeks and at least 3 teams working on it, needless to say, our stakeholders were not pleased with the delay.&lt;/p&gt;

&lt;p&gt;This serves as an example of how overlooking the bigger picture can hinder progress. Considering the problem holistically and making accurate estimations allows for better planning and task coordination. In an alternate scenario, identifying all actors and actions during estimation could have reduced the time. Timely notifications to the involved teams and individuals would have contributed to a more efficient integration. While the task estimation might be more than a single story point, it would have taken less time than the other scenario, and the stakeholders would have been reassured by seeing that everything went smoothly and without delays and the integration would have been carried out more efficiently.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Developing big picture thinking allows us to see how our work fits into the overall system, understand the balance of trade offs, improve our communication and collaboration, and be more productive and innovative.&lt;/p&gt;

&lt;h2&gt;
  
  
  Understanding the Big Picture
&lt;/h2&gt;

&lt;p&gt;In software development big picture thinking goes way beyond just code. Is about understanding or, at the very least, being aware of the relationship between the different parts of a software project. For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The needs of the users and other stakeholders.&lt;/strong&gt; Oftentimes we work on isolated teams/services/areas and it's easy to lose perspective and make decisions that we think are the best for our context, but sometimes what is the best for a part of a system, is not the best for the system as a whole.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The overall architecture of the system.&lt;/strong&gt; We need to be able answer the questions: what are the main components of the system? How do the components interact with each other? How's the system deployed and operated? What are the non-functional requirements of the system, such as performance, security, and scalability? 
These  are not the only questions to answer, but you have the idea. If you don't have the answer for these questions, you better start asking for answers.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The business goals and objectives that the system is intended to support.&lt;/strong&gt; By keeping the business goal in mind, we can design and implement new systems/processes/features that are more likely to succeed.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These are not the only points we can or should consider, but are a good starting point. &lt;/p&gt;

&lt;h2&gt;
  
  
  Benefits of Big Picture Thinking
&lt;/h2&gt;

&lt;p&gt;Developing big picture thinking can give us great benefits, for example: knowing the goal of your project, what services to consume, the technologies used in the system, can help us &lt;strong&gt;make better decisions&lt;/strong&gt; about the design and implementation of our code and be prepared about how future changes might impact the system or the project. It can also help us be more productive by helping us to identify the most important tasks, detect dependencies and estimate the effort to complete and prioritize them. &lt;strong&gt;Innovation&lt;/strong&gt; is also easier once we start to understand the big picture, you start thinking in broader solutions, foreseeing future problems and start taking measures to mitigate them.&lt;/p&gt;

&lt;p&gt;When you can understand the big picture, everybody benefits from it. You can help others understand it, you can justify and communicate better your decisions and understand the ones taken by your stakeholders.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;In the early 1990s, Apple was on the brink of collapse. The company was facing increased competition from IBM and Microsoft, which had both released successful operating systems and computer products. Its bloated product lineup and ineffective marketing led to a deteriorating relationship with customers.&lt;/p&gt;

&lt;p&gt;Key Decisions:&lt;br&gt;
In 1997, Steve Jobs returned as CEO, focusing on innovation and simplifying the product lineup to two desktops and two laptops. He improved the marketing strategy and restored customer relations, stating, "Innovation distinguishes between a leader and a follower."&lt;/p&gt;

&lt;p&gt;Results:&lt;br&gt;
Under Jobs, Apple introduced the iMac in 1998, followed by successful products like the iPod, iPhone, and iPad. Today, Apple, valued over $2 trillion, reflects the power of big picture thinking and bold decisions in turning around adversity.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  How to Develop Big Picture Thinking?
&lt;/h2&gt;

&lt;p&gt;Although some people are able to see it at first glance, naturally, being able to see the big picture is a skill that can be learned and honed. The following are some techniques that can help you to improve your ability to think:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Have a "think" checklist.&lt;/strong&gt; Whenever you have to start working in something ask yourself a couple of questions like:

&lt;ul&gt;
&lt;li&gt;Who's going to use it?&lt;/li&gt;
&lt;li&gt;Which other entities (services, teams, actors) will be involved?&lt;/li&gt;
&lt;li&gt;What is most likely to change over time?&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Practice Second-Order thinking.&lt;/strong&gt; This is a technique of strategic thinking that is, thinking in terms of interactions and time. Second order thinkers ask themselves the question “And then what?” 2 this exercise will help you conceptualize the consequences of your decisions over time.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Make it a habit.&lt;/strong&gt; Practice makes perfect, right? Making habits is hard, but not impossible. First, you need to make time for thinking, you can start blocking some time out of your calendar to make time to think, or you can introduce this "thinking time" into your daily routine and multitask and do it while doing a mechanical task (like walking, showering, doing the dishes). The important thing is to think.3
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Create To-Focus-On Lists.&lt;/strong&gt; Where should your attention be concentrated?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Consider the future and the past.&lt;/strong&gt; Consider past successes, post mortems / case analisys, and future trends while making decisions.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Capture your ideas.&lt;/strong&gt; Take notes, and review them regularly.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ask for feedback.&lt;/strong&gt; Nobody is an island, remember? You need to sync and talk with people, so you don't end up misinterpreting anything important.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;Big picture thinking is a critical skill for IT professionals, particularly software engineers, quality engineers, project managers, SREs, and others involved in complex technological ecosystems. It allows us to understand the context of our work, see how it fits into the overall system, and make informed decisions that align with business goals and objectives.&lt;/p&gt;

&lt;p&gt;Developing big picture thinking takes practice and effort, but it is well worth it. By cultivating this skill, we can enhance our productivity, innovation, and communication, ultimately leading to greater success in our careers.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--w41ZML7O--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xai8dniog7if0rfmmzl5.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--w41ZML7O--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xai8dniog7if0rfmmzl5.jpg" alt="Image description" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Remember:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Big picture thinking goes beyond code and encompasses the entire software ecosystem.&lt;/li&gt;
&lt;li&gt;Understanding the needs of users, system architecture, and business goals is essential.&lt;/li&gt;
&lt;li&gt;Big picture thinking brings significant benefits, including better decision-making, improved productivity, and enhanced innovation.&lt;/li&gt;
&lt;li&gt;Develop big picture thinking skills through techniques like having a "think" checklist, practicing second-order thinking, and regularly reflecting on past experiences and future trends.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And the most important thing to remember: &lt;strong&gt;Big picture thinking is an ongoing journey, not a destination.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Do you want to know more?
&lt;/h2&gt;

&lt;p&gt;Here's some recommended reading.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Thinking in Systems.&lt;/strong&gt; by &lt;strong&gt;Donella H. Meadows&lt;/strong&gt;: This book offers a framework for understanding how systems work and how to make effective interventions.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Range: Why Generalists Triumph in a Specialized World&lt;/strong&gt; by &lt;strong&gt;David Epstein&lt;/strong&gt;: This book argues that generalists are often more successful than specialists, as they are able to see connections across different domains.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Sources:
&lt;/h2&gt;

&lt;p&gt;[1] &lt;a href="https://www.indeed.com/career-advice/career-development/big-picture-thinking-strategies"&gt;Big Picture Thinking: Definition, Strategies and Careers&lt;/a&gt;&lt;br&gt;
[2] &lt;a href="https://fs.blog/second-order-thinking/"&gt;Second-Order Thinking: What Smart People Use to Outperform&lt;/a&gt;&lt;br&gt;
[3] &lt;a href="https://www.linkedin.com/learning/strategic-thinking-2017/welcome-to-strategic-thinking?u=100838786"&gt;Strategic Thinking (2017)&lt;/a&gt;&lt;/p&gt;

</description>
      <category>powerskills</category>
      <category>bigpicturethinking</category>
      <category>problemsolving</category>
      <category>criticalthinking</category>
    </item>
    <item>
      <title>Introduction to Maps in Golang</title>
      <dc:creator>Héctor Vela</dc:creator>
      <pubDate>Wed, 13 Sep 2023 21:56:25 +0000</pubDate>
      <link>https://dev.to/makko/introduction-to-maps-in-golang-5107</link>
      <guid>https://dev.to/makko/introduction-to-maps-in-golang-5107</guid>
      <description>&lt;p&gt;Recently, I had the opportunity to participate as a mentor in an introductory Golang bootcamp. It was a very fulfilling experience to introduce engineers to the fantastic world of Go.&lt;/p&gt;

&lt;p&gt;One of the subjects I had the opportunity to teach was about maps.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog-post-images-and-more.s3.us-east-1.amazonaws.com%2Fprogrammer-hash-maps.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog-post-images-and-more.s3.us-east-1.amazonaws.com%2Fprogrammer-hash-maps.jpg" alt="A programmer working with hash maps as pictured by Dall-e 2"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Introduction to maps
&lt;/h2&gt;

&lt;p&gt;Maps are one of the most useful and versatile data structures. They are present in most of programming languages, you might already know them as Dictionaries in Python, Hash-maps in Java, Objects in JavaScript or associative arrays in PHP, to mention some.&lt;/p&gt;

&lt;p&gt;They provide fast lookups (Maps provide constant-time (O(1)) average-case complexity for insertion, retrieval, and deletion operations), automatic key uniqueness, and dynamic size among other features.&lt;/p&gt;

&lt;p&gt;We can think about maps as containers where we can easily store information and retrieve it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Declaring maps in Go
&lt;/h2&gt;

&lt;p&gt;A map declaration looks like:&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;map&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;KeyType&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="n"&gt;ValueType&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Where &lt;code&gt;KeyType&lt;/code&gt; is a &lt;a href="https://go.dev/ref/spec#Comparison_operators" rel="noopener noreferrer"&gt;type that can be compared&lt;/a&gt;, such as boolean, numeric, string, pointer, channel, interface, struct, or arrays containing only other comparable types.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;ValueType&lt;/code&gt; can be any kind of value.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;products&lt;/span&gt; &lt;span class="k"&gt;map&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="kt"&gt;float64&lt;/span&gt;
&lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"products is of type %T and its value is %#v&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;products&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;products&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;products&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After declaring a map, its value will be &lt;code&gt;nil&lt;/code&gt;. A nil map behaves as an empty map for reads, but if you try to write on it, a runtime panic will be triggered.&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;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;products&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"non existent key"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="c"&gt;// Prints an empty value as the key doesn't exist&lt;/span&gt;
&lt;span class="c"&gt;// Attempting to write to a nil map will result in a runtime panic: assignment to entry in nil map&lt;/span&gt;
&lt;span class="n"&gt;products&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"FashionCap"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="m"&gt;99.99&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Initializing maps
&lt;/h2&gt;

&lt;p&gt;Same as with other types of values, there are a couple of different ways to initialize maps. You can use the &lt;code&gt;make&lt;/code&gt; function, which is a built-in function that allocates and initializes objects like slices, maps, or channels. Alternatively, you can use the short variable declaration. The choice between these methods depends on your specific requirements and team coding standards.&lt;/p&gt;

&lt;p&gt;After initializing a map, we can start adding values to it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;products&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;make&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;map&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="kt"&gt;float64&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;products&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"Cool Hat"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="m"&gt;99.99&lt;/span&gt;
&lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"products is of type %T and its value is %#v&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;products&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;products&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Working with map elements
&lt;/h2&gt;

&lt;p&gt;The syntax needed to work with maps is simple and familiar.&lt;/p&gt;

&lt;p&gt;As mentioned, we can initialize a map with the short variable declaration, so we can use it to initialize a populated map:&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;account&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="k"&gt;map&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s"&gt;"dev"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"691484518277"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;"qa"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;  &lt;span class="s"&gt;"691515518215"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;"stg"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"632515518875"&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;We add values to a map using the map name, the key, and the data to add.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="c"&gt;// mapName[key] = valueToStore&lt;/span&gt;
&lt;span class="n"&gt;account&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"prod"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"369524578943"&lt;/span&gt;
&lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"%#v&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;account&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can obtain values from a map by specifying the key for the data we want.&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;devAccount&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;account&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"dev"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"%q&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;devAccount&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the map doesn't contain a value associated with a given key, the map will return the "zero value" for the value type.&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;uatAccount&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;account&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"uat"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"%q&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;uatAccount&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Map operations
&lt;/h2&gt;

&lt;p&gt;Go provide us with some tools to work with maps. For example, we can count the keys a map has:&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;account&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="k"&gt;map&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s"&gt;"dev"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;  &lt;span class="s"&gt;"691484518277"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;"qa"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;   &lt;span class="s"&gt;"691515518215"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;"stg"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;  &lt;span class="s"&gt;"632515518875"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;"test"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"number of keys:"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;account&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Delete a map entry by key:&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;key&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="s"&gt;"dev"&lt;/span&gt;
&lt;span class="nb"&gt;delete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;account&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When getting a value from a map using its key, the operation returns two values. The second value is a boolean that indicates whether the key exists in the map or not. You can use this boolean value to check if a key is present in the map before attempting to access its value.&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;if&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ok&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;account&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;ok&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"key '%s' not found&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Go introduced a &lt;a href="https://pkg.go.dev/maps@master" rel="noopener noreferrer"&gt;new maps package&lt;/a&gt; in its 1.21 version that introduces new utilities such as copy, clone, maps comparison functions and more!&lt;/p&gt;

&lt;h2&gt;
  
  
  Iterating over maps
&lt;/h2&gt;

&lt;p&gt;We can iterate over a map by using a &lt;code&gt;for&lt;/code&gt; loop with &lt;code&gt;range&lt;/code&gt;. &lt;code&gt;range&lt;/code&gt; allow us to loop through a map obtaining each key and value present in the map:&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;a&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;numberToStr&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;  &lt;span class="s"&gt;"zero"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;  &lt;span class="s"&gt;"one"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;  &lt;span class="s"&gt;"two"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="m"&gt;3&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;  &lt;span class="s"&gt;"three"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="m"&gt;4&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;  &lt;span class="s"&gt;"four"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="m"&gt;5&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;  &lt;span class="s"&gt;"five"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="m"&gt;6&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;  &lt;span class="s"&gt;"six"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="m"&gt;7&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;  &lt;span class="s"&gt;"seven"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="m"&gt;8&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;  &lt;span class="s"&gt;"eight"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="m"&gt;9&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;  &lt;span class="s"&gt;"nine"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="m"&gt;10&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"ten"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="k"&gt;range&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;value&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;If you tried to run the previous sample code, you will find that the map elements are print out of order. The order is random by design. This encourages developers to not rely on key order and prevent developers to make wrong assumptions about the order.&lt;/p&gt;

&lt;p&gt;If you wish to loop through a map in order, then you'll need to do it by yourself. That is, extracting the keys into a slice or array, sort it, and then use the sorted iterable to retrieve the map values by key:&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;a&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;numberToStr&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;  &lt;span class="s"&gt;"zero"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;  &lt;span class="s"&gt;"one"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;  &lt;span class="s"&gt;"two"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="c"&gt;// ...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="c"&gt;// Extract the keys into a slice.&lt;/span&gt;
&lt;span class="n"&gt;keys&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="nb"&gt;make&lt;/span&gt;&lt;span class="p"&gt;([]&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="k"&gt;range&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;keys&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;keys&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;// Sort the keys.&lt;/span&gt;
&lt;span class="n"&gt;sort&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Ints&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;keys&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c"&gt;// Iterate through the sorted keys and access the map elements.&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="k"&gt;range&lt;/span&gt; &lt;span class="n"&gt;keys&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Maps and reference types
&lt;/h2&gt;

&lt;p&gt;Maps are a reference type. This means that a map variable doesn't hold any value, but rather, it points to where the data is present in memory. When you assign a reference type to another variable or is passed as function argument, you are copying the reference, not the data.&lt;/p&gt;

&lt;p&gt;You can think about this somewhat similar to real life tags. You might have a box with toys (the actual map data) labeled with a tag "Toys". You can slap a new tag labeled "Playing items" to the same box. The data is the same (the toy box), but now we have two variables ("Toys"/"Playing items") pointing to the same data.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="c"&gt;// Maps are like tags on a box of toys.&lt;/span&gt;
&lt;span class="n"&gt;toys&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="k"&gt;map&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s"&gt;"1"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"car"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;"2"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"doll"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;// Copy the tag to another box.&lt;/span&gt;
&lt;span class="n"&gt;playingItems&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;toys&lt;/span&gt;

&lt;span class="c"&gt;// Change the contents of the new box.&lt;/span&gt;
&lt;span class="n"&gt;playingItems&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"1"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"ball"&lt;/span&gt;

&lt;span class="c"&gt;// The original box is also updated.&lt;/span&gt;
&lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;toys&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"1"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="c"&gt;// "ball"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Key and values of different types
&lt;/h2&gt;

&lt;p&gt;As previously mentioned, the keys of a map are of a comparable value and the keys can be of any value.&lt;/p&gt;

&lt;p&gt;So, we could think about a case where we could have structs as map keys, this can be useful when associating addresses with specific individuals.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;person&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;firstName&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;
    &lt;span class="n"&gt;lastName&lt;/span&gt;  &lt;span class="kt"&gt;string&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;address&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;streetName&lt;/span&gt;   &lt;span class="kt"&gt;string&lt;/span&gt;
    &lt;span class="n"&gt;number&lt;/span&gt;       &lt;span class="kt"&gt;string&lt;/span&gt;
    &lt;span class="n"&gt;neighborhood&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;
    &lt;span class="n"&gt;zipCode&lt;/span&gt;      &lt;span class="kt"&gt;string&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;peopleAddresses&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="k"&gt;map&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;person&lt;/span&gt;&lt;span class="p"&gt;][]&lt;/span&gt;&lt;span class="n"&gt;address&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;person&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;firstName&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Makko"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;lastName&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;  &lt;span class="s"&gt;"Vela"&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="p"&gt;[]&lt;/span&gt;&lt;span class="n"&gt;address&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;streetName&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;   &lt;span class="s"&gt;"Evergreen Terrace"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;       &lt;span class="s"&gt;"742"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;neighborhood&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Henderson"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;zipCode&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;      &lt;span class="s"&gt;"90210"&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;streetName&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;   &lt;span class="s"&gt;"Spalding Way"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;       &lt;span class="s"&gt;"420"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;neighborhood&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Adamsbert"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;zipCode&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;      &lt;span class="s"&gt;"63637"&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;makko&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;person&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;firstName&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Makko"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;lastName&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;  &lt;span class="s"&gt;"Vela"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;peopleAddresses&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;makko&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can also have cases where we need to use nested maps, for example when representing a hierarchical structure:&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;familyTree&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="k"&gt;map&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="k"&gt;map&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s"&gt;"Juan"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s"&gt;"father"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Miguel"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s"&gt;"mother"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Ana"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="s"&gt;"María"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s"&gt;"father"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Alfredo"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s"&gt;"mother"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Guadalupe"&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="c"&gt;// Accessing nested map values&lt;/span&gt;
&lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Juan's dad is:"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;familyTree&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"Juan"&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="s"&gt;"father"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"María's mom is:"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;familyTree&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"María"&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="s"&gt;"mother"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Map use cases
&lt;/h2&gt;

&lt;p&gt;Among the most common use cases we have:&lt;/p&gt;

&lt;h3&gt;
  
  
  Data association
&lt;/h3&gt;

&lt;p&gt;For example, looking up definitions for words in a dictionary.&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;dictionary&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="k"&gt;map&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s"&gt;"map"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"a diagram or collection of data showing the spatial arrangement or distribution of something over an area"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dictionary&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"map"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Count items
&lt;/h3&gt;

&lt;p&gt;Counting word occurrences in a text is useful, such as in text analysis or generating word clouds:&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;song&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="s"&gt;"Baby Shark, doo-doo, doo-doo, doo-doo, Baby Shark, doo-doo, doo-doo, doo-doo, Baby Shark, doo-doo, doo-doo, doo-doo, Baby Shark"&lt;/span&gt;
&lt;span class="n"&gt;song&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;strings&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ReplaceAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;song&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;","&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;words&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;strings&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;song&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;" "&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;lyricMap&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="k"&gt;map&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;word&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="k"&gt;range&lt;/span&gt; &lt;span class="n"&gt;words&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;found&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;lyricMap&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;word&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;found&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;lyricMap&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;word&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;
        &lt;span class="k"&gt;continue&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;lyricMap&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;word&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"%#v&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;lyricMap&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c"&gt;// output would be: map[string]int{"Baby":4, "Shark":4, "doo-doo":9}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Cache
&lt;/h3&gt;

&lt;p&gt;Maps can also serve as a basic in-memory cache to store and retrieve previously computed values efficiently:&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;cache&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ok&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;cacheMap&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;ok&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c"&gt;// do some expensive operation here to get `data`&lt;/span&gt;
        &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="m"&gt;123&lt;/span&gt;
        &lt;span class="n"&gt;cacheMap&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;
        &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"expensive operation"&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;data&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"serve from cache"&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;data&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
    &lt;span class="c"&gt;// prints "expensive operation"&lt;/span&gt;
    &lt;span class="n"&gt;cache&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"key"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="c"&gt;// prints "serve from cache"&lt;/span&gt;
    &lt;span class="n"&gt;cache&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"key"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Switch
&lt;/h3&gt;

&lt;p&gt;We can take advantage of maps allowing any value types, we can even use functions as map values for implementing dynamic behavior.&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;calculator&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="k"&gt;map&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="kt"&gt;float64&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kt"&gt;float64&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s"&gt;"sum"&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;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="kt"&gt;float64&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kt"&gt;float64&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;a&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="s"&gt;"subtraction"&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;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="kt"&gt;float64&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kt"&gt;float64&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;a&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="s"&gt;"multiplication"&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;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="kt"&gt;float64&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kt"&gt;float64&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;a&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="s"&gt;"division"&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;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="kt"&gt;float64&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kt"&gt;float64&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;a&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;calculator&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"sum"&lt;/span&gt;&lt;span class="p"&gt;](&lt;/span&gt;&lt;span class="m"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;4&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;calculator&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"division"&lt;/span&gt;&lt;span class="p"&gt;](&lt;/span&gt;&lt;span class="m"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;4&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Common errors
&lt;/h2&gt;

&lt;p&gt;We already discussed some caveats we can find while using maps. Lets summarize them:&lt;/p&gt;

&lt;h3&gt;
  
  
  Nil map panic
&lt;/h3&gt;

&lt;p&gt;Remember, maps need to be initialized using make or by using a composite literal before adding values to them.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;myMap&lt;/span&gt; &lt;span class="k"&gt;map&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;
&lt;span class="n"&gt;myMap&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"value"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"something"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Key not found
&lt;/h3&gt;

&lt;p&gt;Reading a non existing key from a map results in the zero value for the type. It's essential to check for the existence of a key to avoid unexpected behavior in your code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="c"&gt;// key not found&lt;/span&gt;
&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;myMap&lt;/span&gt; &lt;span class="k"&gt;map&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;
&lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"%#v&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;myMap&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"non-existing-key"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Maps are reference types
&lt;/h3&gt;

&lt;p&gt;Remember that a map variable doesn't contain de data, but points to its memory location. Failing to account for this can lead to unexpected side effects when passing the map as parameter and this map is modified in the function.&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;updateKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;myMap&lt;/span&gt; &lt;span class="k"&gt;map&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;myMap&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"key"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"some other value"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;myMap&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;map&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;{}&lt;/span&gt;
    &lt;span class="n"&gt;myMap&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"key"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"value"&lt;/span&gt;
    &lt;span class="n"&gt;updateKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;myMap&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"%#v&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;myMap&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Maps and concurrent access
&lt;/h2&gt;

&lt;p&gt;This is a more advanced topic I won't delve into this post, but just a word of warning, maps are not safe for concurrent writes (reads are ok). &lt;em&gt;Concurrent safety&lt;/em&gt; is important because it ensures that a program behaves correctly when multiple threads are executing concurrently.  &lt;/p&gt;

&lt;p&gt;You can read more about this &lt;a href="https://go.dev/doc/faq#atomic_maps" rel="noopener noreferrer"&gt;here&lt;/a&gt;, and if you need to implement concurrent writes, you can use &lt;a href="https://gobyexample.com/mutexes" rel="noopener noreferrer"&gt;sync.Mutex&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;In conclusion, maps are incredibly versatile and powerful data structures in Go, offering a convenient way to associate keys with values. Whether you're looking to create data associations, count items, implement a cache, or even switch between functions dynamically, maps have got you covered.&lt;/p&gt;

&lt;p&gt;However, as with any tool, it's essential to be aware of common pitfalls, such as nil map panics and concurrent access issues, and to handle them with care. By mastering the art of using maps effectively and understanding their behavior, you'll unlock the full potential of this fundamental data structure in your Go programming journey.&lt;/p&gt;

&lt;p&gt;So, go ahead, map out your data, and explore the endless possibilities that maps offer in your Go applications!&lt;/p&gt;

&lt;h3&gt;
  
  
  Post Script
&lt;/h3&gt;

&lt;p&gt;You can find all the code used for this post in &lt;a href="https://gist.github.com/hevela/8c4ce085b58fbec57c38b96a83ad4809" rel="noopener noreferrer"&gt;this gist&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>go</category>
      <category>programming</category>
      <category>beginners</category>
      <category>learning</category>
    </item>
    <item>
      <title>Deploying Lambdas with AWS SAM &amp; GitHub Actions: Step by Step</title>
      <dc:creator>Héctor Vela</dc:creator>
      <pubDate>Fri, 30 Jun 2023 18:02:08 +0000</pubDate>
      <link>https://dev.to/makko/deploying-lambdas-with-aws-sam-github-actions-step-by-step-37mm</link>
      <guid>https://dev.to/makko/deploying-lambdas-with-aws-sam-github-actions-step-by-step-37mm</guid>
      <description>&lt;p&gt;As a Web Developer with over 13 years of experience, I've witnessed the incredible evolution in code delivery. Uploading PHP files onto shared servers is almost ancient history, nowadays we embrace the power of CI/CD Pipelines in the cloud.&lt;/p&gt;

&lt;p&gt;Having a Continuous Integration/Continuous Delivery pipeline becomes invaluable when working in complex applications. It allows for faster and more frequent releases, automating the deployment process and minimizing human errors. This not only saves us time but also ensures consistency across different environments, from development and QA to production and everything in between.&lt;/p&gt;

&lt;p&gt;In this post, I'll walk you through some exciting stuff. We'll create a Lambda to handle GET requests and an authorizer Lambda to validate JWT and control API access, both under the same API Gateway. And we'll finish strong by configuring GitHub Actions to effortlessly deploy our Lambdas to AWS. Ready? Let's get to it!&lt;/p&gt;

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

&lt;p&gt;Before diving in, please ensure that you meet the following requirements:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;An active AWS account with administrative IAM user access.&lt;/li&gt;
&lt;li&gt;AWS CLI installed on your machine.&lt;/li&gt;
&lt;li&gt;Configured AWS credentials for seamless interaction with AWS services.&lt;/li&gt;
&lt;li&gt;AWS SAM CLI installed to facilitate serverless application development.&lt;/li&gt;
&lt;li&gt;A GitHub repository to store your code.&lt;/li&gt;
&lt;li&gt;A local development environment already set up. In this guide, we'll be using Go.&lt;/li&gt;
&lt;li&gt;Docker installed on your machine for local testing purposes.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you're starting from scratch and need assistance with the initial setup, you can refer to the &lt;a href="https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-getting-started.html" rel="noopener noreferrer"&gt;Getting Started with AWS SAM&lt;/a&gt; guide in the AWS Documentation. It provides in-depth information to help you get up and running in no time.&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating your lambdas
&lt;/h2&gt;

&lt;p&gt;We'll be using SAM (Serverless Application Model) to create all of our resources. SAM is an open-source framework designed for building serverless applications on AWS. It utilizes a YAML format, which is a subset of the CloudFormation syntax. With SAM templates, you can easily define functions, APIs, databases, and various other AWS resources using just a few lines of code per resource. During deployment, SAM transforms and expands the SAM syntax into AWS CloudFormation syntax, simplifying the development process and accelerating serverless application building.&lt;/p&gt;

&lt;p&gt;SAM offers a range of templates tailored for common use cases, and with the help of SAM CLI, creating a lambda function is very easy. You can start by using the "hello world" example and modify it according to your requirements.&lt;/p&gt;

&lt;p&gt;Let's get started. Open your terminal and run &lt;code&gt;sam init&lt;/code&gt; to launch the assistant.&lt;/p&gt;

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

&lt;span class="nv"&gt;$ &lt;/span&gt;sam init

You can preselect a particular runtime or package &lt;span class="nb"&gt;type &lt;/span&gt;when using the &lt;span class="sb"&gt;`&lt;/span&gt;sam init&lt;span class="sb"&gt;`&lt;/span&gt; experience.
Call &lt;span class="sb"&gt;`&lt;/span&gt;sam init &lt;span class="nt"&gt;--help&lt;/span&gt;&lt;span class="sb"&gt;`&lt;/span&gt; to learn more.

Which template &lt;span class="nb"&gt;source &lt;/span&gt;would you like to use?
    1 - AWS Quick Start Templates
    2 - Custom Template Location
Choice:


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

&lt;/div&gt;

&lt;p&gt;You'll be presented with two options. Choose option 1. Next, a list of templates will appear, and once again, choose option 1 (Hello World Example).&lt;/p&gt;

&lt;p&gt;Now, it's time to select your runtime. For this guide, I'll select &lt;code&gt;go1.x&lt;/code&gt;. As for the package type, let's choose &lt;code&gt;zip&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The assistant will prompt you with a question about enabling &lt;em&gt;X-Ray tracing&lt;/em&gt; and &lt;em&gt;CloudWatch Application Insight&lt;/em&gt; for the function. Answer &lt;code&gt;y&lt;/code&gt; to enable both.&lt;/p&gt;

&lt;p&gt;Lastly, when asked for the name of your application, provide a suitable name. In my case, I'll name it &lt;code&gt;hello-lambda&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;SAM will create a new folder called &lt;code&gt;hello-lambda&lt;/code&gt; with the following structure:&lt;/p&gt;

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

&lt;span class="nb"&gt;.&lt;/span&gt;
├── Makefile                    &amp;lt;&lt;span class="nt"&gt;--&lt;/span&gt; Make to automate build
├── README.md                   &amp;lt;&lt;span class="nt"&gt;--&lt;/span&gt; This instructions file
├── hello-world                 &amp;lt;&lt;span class="nt"&gt;--&lt;/span&gt; Source code &lt;span class="k"&gt;for &lt;/span&gt;a lambda &lt;span class="k"&gt;function&lt;/span&gt;
│   ├── main.go                 &amp;lt;&lt;span class="nt"&gt;--&lt;/span&gt; Lambda &lt;span class="k"&gt;function &lt;/span&gt;code
│   └── main_test.go            &amp;lt;&lt;span class="nt"&gt;--&lt;/span&gt; Unit tests
└── template.yaml


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

&lt;/div&gt;

&lt;p&gt;Now, you can begin by renaming the &lt;code&gt;hello-world&lt;/code&gt; references with the desired name for your lambda or project, and add the functionality you need. For the sake of simplicity, I'll leave this hello world lambda as is.&lt;/p&gt;

&lt;p&gt;Next, repeat the same process to create the foundation for a Lambda authorizer. I named my lambda &lt;code&gt;lambda-authorizer&lt;/code&gt; and updated the folder and references from &lt;code&gt;hello-world&lt;/code&gt; to &lt;code&gt;authorizer&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Your folder structure should resemble something like this:&lt;/p&gt;

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

&lt;span class="nb"&gt;.&lt;/span&gt;
├──hello-lambda
│  ├──  Makefile
│  ├── README.md
│  ├── hello-world
│  │   ├── main.go
│  │   └── main_test.go
│  └── template.yaml
└──lambda-authorizer
   ├── Makefile                    &amp;lt;&lt;span class="nt"&gt;--&lt;/span&gt; Make to automate build
   ├── README.md                   &amp;lt;&lt;span class="nt"&gt;--&lt;/span&gt; This instructions file
   ├── authorizer                  &amp;lt;&lt;span class="nt"&gt;--&lt;/span&gt; Source code &lt;span class="k"&gt;for &lt;/span&gt;a lambda &lt;span class="k"&gt;function&lt;/span&gt;
   │   ├── main.go                 &amp;lt;&lt;span class="nt"&gt;--&lt;/span&gt; Lambda &lt;span class="k"&gt;function &lt;/span&gt;code
   │   └── main_test.go            &amp;lt;&lt;span class="nt"&gt;--&lt;/span&gt; Unit tests
   └── template.yaml


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

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Note&lt;/em&gt;&lt;/strong&gt;: Make sure to update the go version in the lambdas' &lt;code&gt;go.mod&lt;/code&gt; files to ensure compatibility with the SAM tooling. It is recommended to use at least Go &lt;code&gt;1.18&lt;/code&gt; (I'm using &lt;code&gt;1.20&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;The code for the authorizer is quite straightforward. Currently, it simply validates the presence of a &lt;code&gt;Bearer&lt;/code&gt; token in the &lt;code&gt;Authorization&lt;/code&gt; header. An authorizer lambda must return an &lt;code&gt;APIGatewayCustomAuthorizerResponse&lt;/code&gt; with either an &lt;code&gt;Allow&lt;/code&gt; or &lt;code&gt;Deny&lt;/code&gt; IAM policy.&lt;/p&gt;

&lt;p&gt;Here is the complete code for the authorizer. Feel free to add any additional validation logic you require within the &lt;code&gt;handleRequest&lt;/code&gt; method:&lt;/p&gt;

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

&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;

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

    &lt;span class="s"&gt;"github.com/aws/aws-lambda-go/events"&lt;/span&gt;
    &lt;span class="s"&gt;"github.com/aws/aws-lambda-go/lambda"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;handleRequest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;event&lt;/span&gt; &lt;span class="n"&gt;events&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;APIGatewayCustomAuthorizerRequest&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;events&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;APIGatewayCustomAuthorizerResponse&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;token&lt;/span&gt; &lt;span class="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;AuthorizationToken&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;token&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s"&gt;""&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;strings&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;HasPrefix&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Bearer"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;generatePolicy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Deny"&lt;/span&gt;&lt;span class="p"&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;MethodArn&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;generatePolicy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Allow"&lt;/span&gt;&lt;span class="p"&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;MethodArn&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;lambda&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Start&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;handleRequest&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;generatePolicy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;effect&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;resource&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;events&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;APIGatewayCustomAuthorizerResponse&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;authResponse&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;events&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;APIGatewayCustomAuthorizerResponse&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;PrincipalID&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"user"&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;effect&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="s"&gt;""&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;resource&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="s"&gt;""&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;authResponse&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PolicyDocument&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;events&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;APIGatewayCustomAuthorizerPolicy&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;Version&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"2012-10-17"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;Statement&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="n"&gt;events&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IAMPolicyStatement&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="n"&gt;Action&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;   &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;"execute-api:Invoke"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
                    &lt;span class="n"&gt;Effect&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;   &lt;span class="n"&gt;effect&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="n"&gt;Resource&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;resource&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="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;authResponse&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


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

&lt;/div&gt;
&lt;h2&gt;
  
  
  Building and Packaging Lambdas with SAM
&lt;/h2&gt;

&lt;p&gt;We have our lambdas ready, and technically, we can use the SAM command sam deploy to deploy each lambda individually to AWS. However, before doing that, we need to take a few steps to:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Deploy our lambdas as part of the same API gateway.&lt;/li&gt;
&lt;li&gt;Create the necessary roles for SAM to create resources and enable interaction between our resources.&lt;/li&gt;
&lt;li&gt;Deploy everything with a single command.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;To achieve this, let's create a new &lt;code&gt;template.yaml&lt;/code&gt; file in the root folder, at the same level as &lt;code&gt;hello-lambda&lt;/code&gt; and &lt;code&gt;lambda-authorizer&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;In this file, we'll define a few important components:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The API gateway where our lambdas will be accessible.&lt;/li&gt;
&lt;li&gt;A role that grants permissions to our lambdas to write to CloudWatch.&lt;/li&gt;
&lt;li&gt;The build method for our lambdas.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To save time, let's copy the contents of the &lt;code&gt;template.yaml&lt;/code&gt; file from &lt;code&gt;hello-lambda&lt;/code&gt; and start adding our additional resources.&lt;/p&gt;

&lt;p&gt;First, let's add the resource definition for the authorizer lambda. Note that it will have the same definition as the one in &lt;code&gt;lambda-authorizer/template.yaml&lt;/code&gt;, but without the Events section.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;

  &lt;span class="na"&gt;AuthorizerFunction&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;Type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;AWS::Serverless::Function&lt;/span&gt;
    &lt;span class="na"&gt;Metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;BuildMethod&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;makefile&lt;/span&gt;
    &lt;span class="na"&gt;Properties&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;CodeUri&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;lambda-authorizer/&lt;/span&gt;
      &lt;span class="na"&gt;Handler&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;authorizer/authorizer&lt;/span&gt;
      &lt;span class="na"&gt;Runtime&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;go1.x&lt;/span&gt;
      &lt;span class="na"&gt;Architectures&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;x86_64&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;Then, we will define our API Gateway and specify the authorizer function.:&lt;/p&gt;

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

  &lt;span class="na"&gt;HelloWorldApiGateway&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;Type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;AWS::Serverless::Api&lt;/span&gt;
    &lt;span class="na"&gt;Properties&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;StageName&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;v1&lt;/span&gt;
      &lt;span class="na"&gt;Auth&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;DefaultAuthorizer&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;TokenAuthorizer&lt;/span&gt;
        &lt;span class="na"&gt;Authorizers&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;TokenAuthorizer&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;FunctionArn&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;!GetAtt&lt;/span&gt; &lt;span class="s"&gt;AuthorizerFunction.Arn&lt;/span&gt;
            &lt;span class="na"&gt;Identity&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
              &lt;span class="na"&gt;ReauthorizeEvery&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;Things to note here are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;StageName&lt;/code&gt; is optional, but this value represents the name of the deployment stage for your REST API. It is typically used to distinguish different versions or environments of your API.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;FunctionArn&lt;/code&gt;, as the name implies, is the ARN of the authorizer lambda. Because we are just creating the lambda and we don't know the ARN yet, we are obtaining the ARN value with the &lt;code&gt;GetAtt&lt;/code&gt; function. If you already have a lambda created and&lt;code&gt;&lt;/code&gt;deployed, you can use its ARN here.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ReauthorizeEvery&lt;/code&gt;: This property of &lt;code&gt;Identity&lt;/code&gt; controls the cache for the authorizer lambda. Here, we are disabling the cache by setting the value to 0. This means that every call will pass through the authorizer lambda.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Next, let's add another resource. This resource will define the role our lambda will assume to be able to write to CloudWatch and send traces to X-Ray.&lt;/p&gt;

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

  &lt;span class="na"&gt;ConfigurationLambdaRole&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;Type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;AWS::IAM::Role&lt;/span&gt;
    &lt;span class="na"&gt;Properties&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;AssumeRolePolicyDocument&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;Version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;2012-10-17'&lt;/span&gt;
        &lt;span class="na"&gt;Statement&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;Effect&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Allow&lt;/span&gt;
            &lt;span class="na"&gt;Principal&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
              &lt;span class="na"&gt;Service&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
                &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;lambda.amazonaws.com&lt;/span&gt;
            &lt;span class="na"&gt;Action&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
              &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;sts:AssumeRole&lt;/span&gt;
      &lt;span class="na"&gt;Policies&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;PolicyName&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;HelloLambdaRolePolicy&lt;/span&gt;
          &lt;span class="na"&gt;PolicyDocument&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;Version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;2012-10-17'&lt;/span&gt;
            &lt;span class="na"&gt;Statement&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
              &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;Effect&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Allow&lt;/span&gt;
                &lt;span class="na"&gt;Action&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
                  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;logs:CreateLogGroup&lt;/span&gt;
                  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;logs:CreateLogStream&lt;/span&gt;
                  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;logs:PutLogEvents&lt;/span&gt;
                  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;xray:PutTraceSegments&lt;/span&gt;
                  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;xray:PutTelemetryRecords&lt;/span&gt;
                  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;xray:GetSamplingRules&lt;/span&gt;
                  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;xray:GetSamplingTargets&lt;/span&gt;
                &lt;span class="na"&gt;Resource&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;*'&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;Then, we are going back to the definition of our &lt;code&gt;HelloWorldFunction&lt;/code&gt; to add the role to assume. &lt;/p&gt;

&lt;p&gt;This is the final resource definition:&lt;/p&gt;

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

  &lt;span class="na"&gt;HelloWorldFunction&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;Type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;AWS::Serverless::Function&lt;/span&gt;
    &lt;span class="na"&gt;Metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;BuildMethod&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;makefile&lt;/span&gt;
    &lt;span class="na"&gt;Properties&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;CodeUri&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;hello-lambda/&lt;/span&gt;
      &lt;span class="na"&gt;Handler&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;hello-world/hello-world&lt;/span&gt;
      &lt;span class="na"&gt;Role&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;!GetAtt&lt;/span&gt; &lt;span class="s"&gt;HelloLambdaRole.Arn&lt;/span&gt;
      &lt;span class="na"&gt;Runtime&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;go1.x&lt;/span&gt;
      &lt;span class="na"&gt;Architectures&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;x86_64&lt;/span&gt;
      &lt;span class="na"&gt;Events&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;CatchAll&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;Type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Api&lt;/span&gt;
          &lt;span class="na"&gt;Properties&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;Path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/hello&lt;/span&gt;
            &lt;span class="na"&gt;Method&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;GET&lt;/span&gt;
            &lt;span class="na"&gt;RestApiId&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
              &lt;span class="na"&gt;Ref&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;HelloWorldApiGateway&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;Note that we removed the environment section as we don't need it, but you can use this section to pass Env Var values to your lambda code.&lt;/p&gt;

&lt;p&gt;The values for &lt;code&gt;CodeUri&lt;/code&gt; and &lt;code&gt;Handler&lt;/code&gt; have also changed. The new values follow the pattern:&lt;/p&gt;

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

&lt;span class="na"&gt;CodeUri&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;lt;folder created by sam init&amp;gt;/&lt;/span&gt;
&lt;span class="na"&gt;Handler&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;lt;lambda name&amp;gt;/&amp;lt;binary filename&amp;gt;&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;We also added a new property, &lt;code&gt;Metadata&lt;/code&gt;. This is used to specify a custom build command when compiling the lambda. However, we need to go to each of our lambda's Makefiles and add the following:&lt;/p&gt;

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

&lt;span class="c"&gt;# hello-lambda/Makefile
&lt;/span&gt;&lt;span class="nl"&gt;build-HelloWorldFunction&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="nb"&gt;cd &lt;/span&gt;hello-world&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nv"&gt;GOOS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;linux &lt;span class="nv"&gt;GOARCH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;amd64 &lt;span class="nv"&gt;CGO_ENABLED&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;0 go build &lt;span class="nt"&gt;-o&lt;/span&gt; hello-world main.go
    &lt;span class="nb"&gt;mv &lt;/span&gt;hello-world &lt;span class="p"&gt;$(&lt;/span&gt;ARTIFACTS_DIR&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nl"&gt;.PHONY&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;build-HelloWorldFunction&lt;/span&gt;

&lt;span class="c"&gt;# lambda-authorizer/Makefile
&lt;/span&gt;&lt;span class="nl"&gt;build-AuthorizerFunction&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="nb"&gt;cd &lt;/span&gt;authorizer&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nv"&gt;GOOS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;linux &lt;span class="nv"&gt;GOARCH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;amd64 &lt;span class="nv"&gt;CGO_ENABLED&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;0 go build &lt;span class="nt"&gt;-o&lt;/span&gt; authorizer main.go
    &lt;span class="nb"&gt;mv &lt;/span&gt;authorizer &lt;span class="p"&gt;$(&lt;/span&gt;ARTIFACTS_DIR&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nl"&gt;.PHONY&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;build-AuthorizerFunction&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;What's happening here? let's take &lt;code&gt;hello-lambda&lt;/code&gt; as example:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The Makefile is located at the root level of the &lt;code&gt;hello-lambda&lt;/code&gt; folder. So, we need to change the directory to &lt;code&gt;hello-lambda&lt;/code&gt;, which is the folder containing our &lt;code&gt;go.mod&lt;/code&gt; file.&lt;/li&gt;
&lt;li&gt;We set some flags for building the project:

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;GOOS=linux&lt;/code&gt;: This flag sets the target operating system to Linux.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;GOARCH=amd64&lt;/code&gt;: This flag indicates that the resulting binary is optimized for 64-bit systems, specifically x86_64 processors. &lt;/li&gt;
&lt;li&gt;
&lt;code&gt;CGO_ENABLED=0&lt;/code&gt;: This flag is commonly used when you want to create a pure Go binary without relying on external C libraries. It makes your Go application more easily compiled and executed on different platforms without worrying about compatibility issues with C libraries.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The last change to make in our global template.yaml file is to update the outputs to reference the API Gateway we just defined and the role we are creating:&lt;/p&gt;

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

&lt;span class="na"&gt;Outputs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;HelloWorldAPI&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;Description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;API Gateway endpoint URL for Prod environment for First Function&lt;/span&gt;
    &lt;span class="na"&gt;Value&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;!Sub&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://${HelloWorldApiGateway}.execute-api.${AWS::Region}.amazonaws.com/v1/hello/"&lt;/span&gt;
  &lt;span class="na"&gt;HelloWorldFunction&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;Description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;First Lambda Function ARN&lt;/span&gt;
    &lt;span class="na"&gt;Value&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;!GetAtt&lt;/span&gt; &lt;span class="s"&gt;HelloWorldFunction.Arn&lt;/span&gt;
  &lt;span class="na"&gt;HelloWorldFunctionIamRole&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;Description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Explicit IAM Role created for Hello World function&lt;/span&gt;
    &lt;span class="na"&gt;Value&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;!GetAtt&lt;/span&gt; &lt;span class="s"&gt;HelloLambdaRole.Arn&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;You can view the final and complete &lt;a href="https://github.com/hevela/sam-lambdas/blob/main/template.yaml" rel="noopener noreferrer"&gt;template.yml file here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now we can start checking if everything works as expected. So lets build the project!&lt;/p&gt;

&lt;p&gt;In your terminal, change directories to the project root and run:&lt;/p&gt;

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

&lt;span class="nv"&gt;$ &lt;/span&gt;sam build


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

&lt;/div&gt;

&lt;p&gt;If everything is correct, you should see something like:&lt;/p&gt;

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

Build Succeeded

Built Artifacts  : .aws-sam/build
Built Template   : .aws-sam/build/template.yaml

Commands you can use next
&lt;span class="o"&gt;=========================&lt;/span&gt;
&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="k"&gt;*&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; Validate SAM template: sam validate
&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="k"&gt;*&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; Invoke Function: sam &lt;span class="nb"&gt;local &lt;/span&gt;invoke
&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="k"&gt;*&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; Test Function &lt;span class="k"&gt;in &lt;/span&gt;the Cloud: sam &lt;span class="nb"&gt;sync&lt;/span&gt; &lt;span class="nt"&gt;--stack-name&lt;/span&gt; &lt;span class="o"&gt;{{&lt;/span&gt;stack-name&lt;span class="o"&gt;}}&lt;/span&gt; &lt;span class="nt"&gt;--watch&lt;/span&gt;
&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="k"&gt;*&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; Deploy: sam deploy &lt;span class="nt"&gt;--guided&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;If you encounter any errors, here are some common issues to check:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Misspelled resource names or wrong paths in &lt;code&gt;template.yaml&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Incompatible (old) Go version.&lt;/li&gt;
&lt;li&gt;Misspelled attributes in &lt;code&gt;template.yaml&lt;/code&gt;. A common error is using &lt;code&gt;.arn&lt;/code&gt; instead of &lt;code&gt;.Arn&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;At this point, we should be able to deploy our lambdas using SAM CLI. You can do so by running:&lt;/p&gt;

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

&lt;span class="nv"&gt;$ &lt;/span&gt;sam deploy &lt;span class="nt"&gt;--guided&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;An assistant will ask you for some information about your project and your AWS account, such as the name to give the stack, the region for deployment, and if you need to review changes before applying. Once you provide the required details, you should be good to go! However, we don't want to manually deploy our lambdas. Let's see how we can set up a GitHub workflow and leverage some cool features of SAM.&lt;/p&gt;

&lt;p&gt;After building our project and ensuring everything is in order, it's a good time to run:&lt;/p&gt;

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

&lt;span class="nv"&gt;$ &lt;/span&gt;sam pipeline init &lt;span class="nt"&gt;--bootstrap&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;This command will initiate an interactive assistant that guides you through creating the necessary AWS infrastructure resources for SAM to deploy your code. During the process, you will be prompted to &lt;em&gt;select a user permissions provider&lt;/em&gt;. Choose OpenID Connect (OIDC), which will create a role for the GitHub workflow to deploy our project and monitor the creation process.&lt;/p&gt;

&lt;p&gt;The assistant will also assist you in setting up a multi-stage deployment. It will ask you which branches should be pushed to the Dev environment (usually &lt;code&gt;dev&lt;/code&gt; or &lt;code&gt;development&lt;/code&gt;) and which branch should be deployed to the Production environment (usually &lt;code&gt;main&lt;/code&gt; branch).&lt;/p&gt;

&lt;p&gt;Once you complete the questionnaire, the bootstrapping process will begin. When it finishes, you'll have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A new CloudFormation Stack with the resources required by SAM and GitHub Actions.
&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog-post-images-and-more.s3.amazonaws.com%2Fsam-cloudformation-stack.png" alt="sam-cloudformation-stack"&gt;
&lt;/li&gt;
&lt;li&gt;An IAM role assumed by AWS CloudFormation when applying the changeset.&lt;/li&gt;
&lt;li&gt;An IAM role assumed by the GitHub Workflow to deploy our artifacts.
&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog-post-images-and-more.s3.amazonaws.com%2Fsam-created-roles.png" alt="sam-created-roles"&gt;
&lt;/li&gt;
&lt;li&gt;A pair of S3 buckets used to upload your AWS CloudFormation template and store output logs.
&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog-post-images-and-more.s3.amazonaws.com%2Fsam-s3-buckets.png" alt="sam-s3-buckets"&gt;
&lt;/li&gt;
&lt;li&gt;A new GitHub workflow file that contains everything you need to run your deployment pipeline upon merging. Remember to add, commit, and push this file to your repository.
&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog-post-images-and-more.s3.amazonaws.com%2Fworkflow-location.png" alt="workflow-location"&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you are the owner of both the AWS account and the repository, and you have successfully completed the bootstrap process, you're all set! You can now create a new pull request to the specified Dev or Production environment branch, and the GitHub workflow will kick off.&lt;/p&gt;

&lt;p&gt;You can monitor the deployment process either in the Actions tab of your GitHub repository or in the AWS console, specifically in the CloudFormation service panel.&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog-post-images-and-more.s3.amazonaws.com%2Fcloudformation-stack-create-complete.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog-post-images-and-more.s3.amazonaws.com%2Fcloudformation-stack-create-complete.png" alt="cloudformation-stack-create-complete"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog-post-images-and-more.s3.amazonaws.com%2Fgithub-actions-workflow-output.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog-post-images-and-more.s3.amazonaws.com%2Fgithub-actions-workflow-output.png" alt="github-actions-workflow-output"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Note that in the logs displayed for the deployment job in GitHub, there is an "Outputs" section where you can find the API Gateway URL for the lambda function. Let's give it a try!&lt;/p&gt;

&lt;p&gt;First, let's check if the authorizer lambda is working correctly by making a request to our API without an &lt;code&gt;Authorization&lt;/code&gt; header:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Request&lt;/strong&gt;&lt;/p&gt;

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

curl &lt;span class="nt"&gt;--location&lt;/span&gt; &lt;span class="s1"&gt;'https://qk1d1uv590.execute-api.us-east-1.amazonaws.com/v1/hello/'&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Response&lt;/strong&gt;&lt;br&gt;
We should receive an HTTP status code &lt;code&gt;401&lt;/code&gt; (Unauthorized).&lt;/p&gt;

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

&lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"message"&lt;/span&gt;: &lt;span class="s2"&gt;"Unauthorized"&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;Now, let's add a JWT to our request:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Request&lt;/strong&gt;&lt;/p&gt;

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

curl &lt;span class="nt"&gt;--location&lt;/span&gt; &lt;span class="s1"&gt;'https://qk1d1uv590.execute-api.us-east-1.amazonaws.com/v1/hello/'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;--header&lt;/span&gt; &lt;span class="s1"&gt;'Authorization: Bearer token.jwt.value'&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Response&lt;/strong&gt;&lt;/p&gt;

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

Hello, &amp;lt;your IP should appear here&amp;gt;



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

&lt;/div&gt;

&lt;p&gt;And there you have it! We did it! Let's recap and see what we have accomplished:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Created a Lambda function&lt;/li&gt;
&lt;li&gt;Created an authorizer lambda&lt;/li&gt;
&lt;li&gt;Created a SAM template to manage all of our resources in one place&lt;/li&gt;
&lt;li&gt;Used SAM CLI to create the necessary roles for resource creation and deployment, as well as an OIDC role for GitHub Actions to assume and run our jobs&lt;/li&gt;
&lt;li&gt;Completed the setup of our CI/CD pipeline&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;But wait! There's more!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you are the owner or admin of the AWS account, you can stop reading here. But what happens when you have a limited AWS role, or you don't need to deploy to multiple stages?&lt;/p&gt;

&lt;p&gt;That was the case for me. I was working for a client (the owner of the AWS account) and my AWS role couldn't create resources "directly". Additionally, SAM was already bootstrapped, and I only needed to deploy to a single stage. As a result, I didn't benefit from running &lt;code&gt;sam pipeline init --bootstrap&lt;/code&gt; or &lt;code&gt;sam pipeline bootstrap&lt;/code&gt;, which would have set up the OIDC role, GitHub Workflow definition, and AWS stages.&lt;/p&gt;

&lt;p&gt;So let's go back a bit and imagine that we just finished modifying our &lt;code&gt;template.yaml&lt;/code&gt; file and ran &lt;code&gt;sam build&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting Up GitHub Actions Workflow
&lt;/h2&gt;

&lt;p&gt;Ok. Let's take a step back for a moment. What exactly are these GitHub Actions?&lt;/p&gt;

&lt;p&gt;GitHub Actions is a feature of GitHub that allows us to automate our software development workflows within GitHub repositories. It can be used for continuous integration and continuous delivery (CI/CD) of code, as well as automating other software workflows such as building or testing code directly from GitHub.&lt;/p&gt;

&lt;p&gt;To create and define a workflow, you need to create a YAML file in the &lt;code&gt;.github/workflows/&lt;/code&gt; folder of your repository. The name of the file doesn't matter. A workflow consists of one or more events that trigger the workflow, one or more jobs that execute on runner machines, and a series of steps within each job. Each step can run a script that you define or an action, which is a reusable extension that simplifies your workflow.&lt;/p&gt;

&lt;p&gt;Now, let's create our workflow file. I'll create the file &lt;code&gt;.github/workflows/dev-deploy.yaml&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;First, we specify the &lt;a href="https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#permissions" rel="noopener noreferrer"&gt;permissions&lt;/a&gt; we want to give to the GitHub Workflow runner. These permissions modify the default permissions granted to the GITHUB_TOKEN, allowing us to add or remove access as required:&lt;/p&gt;

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

&lt;span class="na"&gt;permissions&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;id-token&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;write&lt;/span&gt; &lt;span class="c1"&gt;# This is required for requesting the JWT&lt;/span&gt;
  &lt;span class="na"&gt;contents&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;read&lt;/span&gt; &lt;span class="c1"&gt;# This is required for actions/checkout&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;Next, we indicate the event that will trigger this workflow:&lt;/p&gt;

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

&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;push&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;branches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;main&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;In this case, we're telling the Workflow runner to execute the workflow whenever there are new changes pushed to the main branch. You can utilize &lt;a href="https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows" rel="noopener noreferrer"&gt;various events&lt;/a&gt; for different triggers.&lt;/p&gt;

&lt;p&gt;Now, let's move on to the main part of the workflow: the jobs. Each job runs in a runner environment specified by &lt;code&gt;runs-on&lt;/code&gt;. A job consists of a sequence of tasks called steps. Steps can run commands, set up tasks, or execute an action within your repository, a public repository, or an action published in a Docker registry.&lt;/p&gt;

&lt;p&gt;For more information about &lt;a href="https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobs" rel="noopener noreferrer"&gt;Jobs&lt;/a&gt; and &lt;a href="https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idsteps" rel="noopener noreferrer"&gt;Steps&lt;/a&gt;, you can refer to the &lt;a href="https://docs.github.com/en/actions/quickstart" rel="noopener noreferrer"&gt;official documentation site&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Now, let's take a look at the job and steps we'll be using to deploy our resources:&lt;/p&gt;

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

    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v3&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;aws-actions/setup-sam@v2&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;use-installer&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;aws-actions/configure-aws-credentials@v2&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;aws-region&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;us-east-1&lt;/span&gt;
          &lt;span class="na"&gt;role-duration-seconds&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1800&lt;/span&gt;
          &lt;span class="na"&gt;role-skip-session-tagging&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
          &lt;span class="na"&gt;role-to-assume&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;arn:aws:iam::269174633178:role/aws-sam-cli-managed-dev-pipe-PipelineExecutionRole-1TGFGMZ8QQ4DO&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/setup-go@v2&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;go-version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;1.20'&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
          &lt;span class="s"&gt;# Define a list of folders (lambda_folder/code_folder) to run go mod tidy in.&lt;/span&gt;
          &lt;span class="s"&gt;folders=(&lt;/span&gt;
            &lt;span class="s"&gt;"lambda-authorizer/authorizer"&lt;/span&gt;
            &lt;span class="s"&gt;"hello-lambda/hello-world"&lt;/span&gt;
          &lt;span class="s"&gt;)&lt;/span&gt;
          &lt;span class="s"&gt;# Loop through each folder and run 'go mod tidy'&lt;/span&gt;
          &lt;span class="s"&gt;for folder in "${folders[@]}"; do&lt;/span&gt;
            &lt;span class="s"&gt;echo "Running 'go mod tidy' in $folder"&lt;/span&gt;
            &lt;span class="s"&gt;cd $folder&lt;/span&gt;
            &lt;span class="s"&gt;go mod tidy -go=1.20&lt;/span&gt;
            &lt;span class="s"&gt;cd ../..&lt;/span&gt;
          &lt;span class="s"&gt;done&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;sam build&lt;/span&gt;
      &lt;span class="c1"&gt;# Prevent prompts and failure when the stack is unchanged&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;sam deploy --no-confirm-changeset --no-fail-on-empty-changeset --role-arn arn:aws:iam::269174633178:role/aws-sam-cli-managed-dev-p-CloudFormationExecutionR-830GQUQ9J19P --stack-name sam-lambdas --resolve-s3 --s3-prefix "sam-lambdas" --region us-east-1 --capabilities CAPABILITY_IAM&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;Here, we have only one step, but several things are happening. First, we are utilizing some existing GitHub Actions. The &lt;code&gt;uses&lt;/code&gt; keyword is used to specify an action that should be executed as part of the workflow, and &lt;code&gt;with: &amp;lt;parameters&amp;gt;&lt;/code&gt; is a set of key-value pairs where the key represents the input parameter name expected by the action, and the value represents the value you want to assign to that parameter. In this case, we are using actions to check out the code, install SAM CLI in the GitHub runner, and build and deploy our project.&lt;/p&gt;

&lt;p&gt;Lastly, the &lt;code&gt;run&lt;/code&gt; command is used to execute command-line programs using the operating system's shell. As you can see here, we are running the &lt;code&gt;go mod tidy&lt;/code&gt; command in each of our lambdas, ensuring that our project builds reliably and uses the correct versions of its dependencies.&lt;/p&gt;

&lt;p&gt;The final &lt;code&gt;run&lt;/code&gt; command deploys our project with the following parameters:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;--no-confirm-changeset&lt;/code&gt;: Prompts to confirm whether the AWS SAM CLI should deploy the computed changeset.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;--no-fail-on-empty-changeset&lt;/code&gt;: Specifies whether to return a non-zero exit code if there are no changes to make to the stack. This prevents the workflow from being marked as failed if there are no changes in the project.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;--role-arn&lt;/code&gt;: The Amazon Resource Name (ARN) of an IAM role that AWS CloudFormation assumes when applying the changeset. In this case, I'm reusing the roles created during the SAM bootstrap process. However, you can refer to &lt;a href="https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/configuring-openid-connect-in-amazon-web-services" rel="noopener noreferrer"&gt;this guide&lt;/a&gt; to create a role specifically for use in GitHub workflows.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;--stack-name&lt;/code&gt;: The name of the CloudFormation stack.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;--resolve-s3&lt;/code&gt;: Automatically creates an Amazon S3 bucket to use for packaging and deploying during non-guided deployments.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;--s3-prefix&lt;/code&gt;: The prefix added to the names of the artifacts that are uploaded to the Amazon S3 bucket.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;--region&lt;/code&gt;: The AWS Region to deploy to.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;--capabilities&lt;/code&gt;: A list of capabilities that must be specified to allow AWS CloudFormation to create certain stacks.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can learn more about these and other &lt;code&gt;sam deploy&lt;/code&gt; options in the &lt;a href="https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-cli-command-reference-sam-deploy.html" rel="noopener noreferrer"&gt;official documentation&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;And that's it! Once you have pushed your workflow file to your repository, you should see the workflow start. You can monitor its progress in the "Actions" tab of your repository.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog-post-images-and-more.s3.amazonaws.com%2Fgithub-actions-workflows.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblog-post-images-and-more.s3.amazonaws.com%2Fgithub-actions-workflows.png" alt="github-actions-workflows"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Some common issues you might encounter are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;"An error occurred (AccessDenied) when calling the PutObject operation: Access Denied."&lt;/em&gt;

&lt;ul&gt;
&lt;li&gt;This means the OIDC role doesn't have the necessary permissions. It should have access to most CloudFormation and S3 actions.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;em&gt;"Missing option 'some option', 'sam deploy --guided' can be used to provide and save the needed parameters for future deployments."&lt;/em&gt;

&lt;ul&gt;
&lt;li&gt;As the message implies, an option might be missing in your &lt;code&gt;sam deploy&lt;/code&gt; command.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conclusion and Best Practices
&lt;/h2&gt;

&lt;p&gt;We have covered a lot in this article! In conclusion, we explored the capabilities of AWS Serverless Application Model (SAM) templates for creating Lambdas, implementing Authorizer Lambdas, defining AWS resources in a stack, deploying our stack, and setting up a CI/CD pipeline with GitHub Workflows.&lt;/p&gt;

&lt;p&gt;SAM templates are a powerful and efficient approach to developing serverless applications. They allow us to define our application's infrastructure and functions in a single template file. With SAM, we can easily manage and deploy our serverless applications, ensuring scalability, reliability, and fast evolution. When combined with GitHub Workflows, we have a seamless CI/CD pipeline that automates our deployments and keeps our application updates flowing smoothly. With these awesome tools at our disposal, we are ready to build and deploy apps like professionals!&lt;/p&gt;

&lt;p&gt;However, this article only scratches the surface, and there are many more topics to explore. For example, we didn't cover best practices. When deploying Lambdas with SAM and GitHub Actions, there are some best practices and recommendations to consider:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Continuous Integration and Deployment (CI/CD): We set up a CI/CD pipeline to deploy our stack, but it's common to use GitHub Actions to automate the build, test, and deployment process.&lt;/li&gt;
&lt;li&gt;Environment-specific Configuration: Use environment variables to manage configuration values such as API keys, database connections, and other sensitive information. GitHub Secrets or AWS Systems Manager Parameter Store can be used to securely store and retrieve these variables during the CI/CD process.&lt;/li&gt;
&lt;li&gt;Automated Testing: Implement automated tests for your Lambdas to ensure their functionality.&lt;/li&gt;
&lt;li&gt;Security and Permissions: Follow the principle of least privilege when assigning IAM roles and permissions to your Lambdas. Only grant the necessary permissions required for their specific functionality. Avoid using long-lived AWS credentials (&lt;code&gt;AWS_ACCESS_KEY_ID&lt;/code&gt;, &lt;code&gt;AWS_SECRET_ACCESS_KEY&lt;/code&gt;) and &lt;strong&gt;use roles instead&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Logging and Monitoring: Enable logging in your Lambdas and use CloudWatch Logs for log management. Implement monitoring and alerting using CloudWatch Alarms or third-party monitoring tools to detect issues and ensure your Lambdas work as intended.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And that's it, friends! You can take a look at the repository with the &lt;a href="https://github.com/hevela/sam-lambdas" rel="noopener noreferrer"&gt;full code here&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Some recommended reading
&lt;/h2&gt;

&lt;p&gt;Would you like to know more? click here to know more!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;AWS SAM:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/what-is-sam.html" rel="noopener noreferrer"&gt;AWS SAM Developer Guide&lt;/a&gt; - Official documentation for AWS SAM, providing an overview, concepts, and examples.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/aws/serverless-application-model" rel="noopener noreferrer"&gt;AWS SAM GitHub Repository&lt;/a&gt; - The official GitHub repository for AWS SAM. It contains code samples, templates, and community contributions.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;AWS Lambda:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://docs.aws.amazon.com/lambda/latest/dg/welcome.html" rel="noopener noreferrer"&gt;AWS Lambda Developer Guide&lt;/a&gt; - Official documentation for AWS Lambda, covering various aspects, including deployment, programming model, and best practices.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/aws/aws-lambda-go" rel="noopener noreferrer"&gt;AWS Lambda GitHub Repository&lt;/a&gt; - The official GitHub repository for AWS Lambda. It includes examples, guides, and resources specifically for working with Lambda in Go.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;GitHub Actions:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://docs.github.com/en/actions" rel="noopener noreferrer"&gt;GitHub Actions Documentation&lt;/a&gt; - The official documentation for GitHub Actions, covering topics such as workflows, syntax, and available actions.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/marketplace?type=actions" rel="noopener noreferrer"&gt;GitHub Actions Marketplace&lt;/a&gt; - A marketplace of pre-built actions that can be used in your GitHub Actions workflows. You can search for actions related to AWS, SAM, or other specific needs.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Examples and Tutorials:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://aws.amazon.com/serverless/serverlessrepo/" rel="noopener noreferrer"&gt;AWS Serverless Application Repository&lt;/a&gt; - A repository of serverless applications built using AWS SAM. You can explore and deploy ready-to-use applications or learn from their implementation.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://docs.github.com/en/actions/examples" rel="noopener noreferrer"&gt;GitHub Actions Examples&lt;/a&gt; - Example workflows that demonstrate the CI/CD features of GitHub Actions.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>aws</category>
      <category>sam</category>
      <category>serverless</category>
      <category>githubactions</category>
    </item>
    <item>
      <title>Instrumenting Go microservices with Gin and AWS X-Ray</title>
      <dc:creator>Héctor Vela</dc:creator>
      <pubDate>Tue, 21 Mar 2023 22:57:24 +0000</pubDate>
      <link>https://dev.to/makko/instrumenting-go-microservices-with-gin-and-aws-x-ray-4e82</link>
      <guid>https://dev.to/makko/instrumenting-go-microservices-with-gin-and-aws-x-ray-4e82</guid>
      <description>&lt;p&gt;In a microservice architecture, operations often span multiple services and resources such as gateways, microservices, load balancers, and databases. The distributed nature of microservices is what makes software instrumentation valuable.&lt;/p&gt;

&lt;p&gt;If our code provides traces, metrics, and logs, we can say that it is instrumented, meaning we are able to observe how our system is performing.&lt;/p&gt;

&lt;p&gt;Service instrumentation is especially useful for identifying and troubleshooting performance issues and errors. The data collected can also be used for capacity planning by helping us understand the traffic and usage patterns of our applications.&lt;/p&gt;

&lt;p&gt;There are several solutions for services instrumentation, such as &lt;a href="https://opentelemetry.io/" rel="noopener noreferrer"&gt;OpenTelemetry&lt;/a&gt;, &lt;a href="https://zipkin.io/" rel="noopener noreferrer"&gt;Zipkin&lt;/a&gt; and &lt;a href="https://www.datadoghq.com/" rel="noopener noreferrer"&gt;datadog&lt;/a&gt;. AWS also offers an &lt;a href="https://aws-otel.github.io/" rel="noopener noreferrer"&gt;OpenTelemetry Distro&lt;/a&gt; to be able to use OpenTelemetry as observability backend while using X-Ray or any other third party solution to receive tracing telemetry data and provide processing, aggregation, and visualizations of that data.&lt;/p&gt;

&lt;p&gt;In this post, I'm going to tell you about my experience instrumenting a Go microservice using Gin, with X-Ray.&lt;/p&gt;

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

&lt;p&gt;Gin is a lightweight and high-performance web framework for the Go programming language, designed to make it easy to build fast and scalable web applications. &lt;/p&gt;

&lt;p&gt;It features a minimalistic API, a robust router, middleware support, and built-in security features, making it an ideal choice for building microservices and other high-performance web applications. &lt;/p&gt;

&lt;p&gt;While Gin may have a steep learning curve and limited built-in features, its simplicity and extensibility make it a popular choice for developers who prioritize performance and scalability.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Creating a gin service from scratch is out of the scope of this post&lt;/strong&gt;, but you can read more about gin in the &lt;a href="https://gin-gonic.com/docs/" rel="noopener noreferrer"&gt;official documentation page.&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  AWS X-Ray
&lt;/h2&gt;

&lt;p&gt;AWS X-Ray is an AWS service that collects data about requests served by your application and provides tools for viewing, filtering, and gaining insights into that data to identify issues and optimization opportunities.&lt;/p&gt;

&lt;p&gt;Some pros of X-Ray over other similar tools are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Integration with some AWS services&lt;/li&gt;
&lt;li&gt;No extra infrastructure to manage (daemon included on AWS Elastic Beanstalk and AWS Lambda platforms)&lt;/li&gt;
&lt;li&gt;Can work as a visualizer only (using OpenTelemetry as Tracer)&lt;/li&gt;
&lt;li&gt;For supported services, X-Ray SDK can automatically send and trace request IDs across services&lt;/li&gt;
&lt;li&gt;Managed by AWS&lt;/li&gt;
&lt;li&gt;First 100k traces per month are free&lt;/li&gt;
&lt;li&gt;First 1,000,000 traces retrieved or scanned each month are free.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;However, some of its cons are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;AWS X-Ray can only be used with applications running on Amazon EC2, Amazon EC2 container service, AWS Lambda, and AWS Elastic Beanstalk.&lt;/li&gt;
&lt;li&gt;After exhausting the free traces for the month, every trace indexed or queried has a cost.&lt;/li&gt;
&lt;li&gt;Limited language support: While X-Ray provides SDKs for several programming languages, it doesn't support every language or platform, which may limit its usefulness in certain scenarios.&lt;/li&gt;
&lt;li&gt;Vendor lock-in: Using X-Ray may lead to vendor lock-in with AWS, as it is a proprietary service only available on the AWS platform. This may limit your ability to switch to other cloud providers or tools in the future.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If, after reading some of the pros and cons, you are still inclined to use X-Ray, then you can continue reading.&lt;/p&gt;

&lt;h3&gt;
  
  
  Requirements
&lt;/h3&gt;

&lt;p&gt;To view trace information in AWS, you need an AWS account and an application running on AWS infrastructure or integrated with AWS services. In addition, you'll need:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;An instance of the X-Ray daemon, which can be run as a binary or as a Docker container. You can find detailed instructions on how to run and configure it &lt;a href="https://docs.aws.amazon.com/xray/latest/devguide/xray-daemon-local.html" rel="noopener noreferrer"&gt;here&lt;/a&gt;. For this article, I'll be using the OS X binary.&lt;/li&gt;
&lt;li&gt;Your application must have the necessary permissions to interact with AWS X-Ray service and other AWS services that it uses.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  IAM Role
&lt;/h4&gt;

&lt;p&gt;To enable your application to send traces to X-Ray, you need to provide the X-Ray daemon with a role. To create the role, go to the "Roles" section in the AWS Web Console for the IAM service and click on the "Create Role" button.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9megb6yhvjrh0mg1xudb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9megb6yhvjrh0mg1xudb.png" alt="Create a new role"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the wizard, select "AWS Account" for Trusted Entity and click "Next". On the next screen, search for the permissions policy named "AWSXRayDaemonWriteAccess". Click "Next" to proceed.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkf6n8y4kvzx061jq3rr7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkf6n8y4kvzx061jq3rr7.png" alt="Name, review, and create"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Add a name and description for the role, and then click "Create Role". This will take you back to the roles list. Look for the role you just created to view and copy the role ARN.&lt;/p&gt;

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

&lt;h3&gt;
  
  
  X-Ray Daemon
&lt;/h3&gt;

&lt;p&gt;Now that we've created the daemon role, let's configure and run it.&lt;/p&gt;

&lt;p&gt;For my local setup, I only needed to change a few settings, such as the log level, setting the local mode to true, and adding the X-Ray role and the AWS region.&lt;/p&gt;

&lt;p&gt;Here's the config file I used:&lt;/p&gt;

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

&lt;span class="c1"&gt;# Send segments to AWS X-Ray service in a specific region&lt;/span&gt;
&lt;span class="na"&gt;Region&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;us-west-2"&lt;/span&gt;
&lt;span class="na"&gt;Socket&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="c1"&gt;# Change the address and port on which the daemon listens for UDP packets containing segment documents.&lt;/span&gt;
  &lt;span class="na"&gt;UDPAddress&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;127.0.0.1:2000"&lt;/span&gt;
  &lt;span class="c1"&gt;# Change the address and port on which the daemon listens for HTTP requests to proxy to AWS X-Ray.&lt;/span&gt;
  &lt;span class="na"&gt;TCPAddress&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;127.0.0.1:2000"&lt;/span&gt;
&lt;span class="na"&gt;Logging&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="c1"&gt;# Change the log level, from most verbose to least: dev, debug, info, warn, error, prod (default).&lt;/span&gt;
  &lt;span class="na"&gt;LogLevel&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;dev"&lt;/span&gt;
&lt;span class="c1"&gt;# Turn on local mode to skip EC2 instance metadata check.&lt;/span&gt;
&lt;span class="na"&gt;LocalMode&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;span class="c1"&gt;# Assume an IAM role to upload segments to a different account.&lt;/span&gt;
&lt;span class="na"&gt;RoleARN&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;arn:aws:iam::269174633178:role/X-Ray_Daemon_role"&lt;/span&gt;
&lt;span class="c1"&gt;# Daemon configuration file format version.&lt;/span&gt;
&lt;span class="na"&gt;Version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;You can learn more about other config values in the &lt;a href="https://docs.aws.amazon.com/xray/latest/devguide/xray-daemon-configuration.html" rel="noopener noreferrer"&gt;AWS X-Ray Developer Guide.&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Instrumenting your Go microservice.
&lt;/h3&gt;

&lt;p&gt;Now that we have the X-Ray daemon configured and running, we can add instrumentation to our service.&lt;/p&gt;

&lt;p&gt;AWS recommends to start by tracing incoming requests by wrapping the service handlers with &lt;code&gt;xray.Handler&lt;/code&gt;. However, since we are using Gin, the approach we'll implement is slightly different.&lt;/p&gt;

&lt;p&gt;While looking for resources about how to instrument a gin application, I found this &lt;a href="https://github.com/oroshnivskyy/go-gin-aws-x-ray" rel="noopener noreferrer"&gt;middleware by Oroshnivskyy&lt;/a&gt; which is based in the &lt;a href="https://github.com/aws/aws-xray-sdk-go/blob/1e154184282bb3b0166cb1b154f2b4abed0b1e6f/xray/handler.go#L99" rel="noopener noreferrer"&gt;x-ray handler function&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;This middleware will start and close a segment for every request received. It also, will take care of handling the trace ID header (&lt;code&gt;"x-amzn-trace-id"&lt;/code&gt;), which is a header that contains an ID value that will be generated for each new request and will be propagated across all of our microservices.&lt;/p&gt;

&lt;p&gt;So let's add the middleware to the routes we want to instrument:&lt;/p&gt;

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

&lt;span class="c"&gt;// as part of my gin routes&lt;/span&gt;
&lt;span class="n"&gt;v1&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GET&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/auth/roles"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;xraymid&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Middleware&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;xray&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewFixedSegmentNamer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"GetRoles"&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt; &lt;span class="n"&gt;controller&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetRoles&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;Here, we are adding the (aliased as xraymid) x-ray gin middleware to a route of the group &lt;code&gt;v1&lt;/code&gt;. The value passed as argument to &lt;code&gt;NewFixedSegmentNamer&lt;/code&gt; must be set to a descriptive name for your route. This will be the name of the main trace group for this endpoint.&lt;/p&gt;

&lt;p&gt;Alright! now let's see if it works! Start the service and verify the Daemon is running.&lt;/p&gt;

&lt;p&gt;After making a request, we can see the in the daemon logs something like:&lt;/p&gt;

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

2023-03-21T13:10:47-06:00 [Debug] Received request on HTTP Proxy server : /GetSamplingRules
2023-03-21T13:10:48-06:00 [Debug] processor: sending partial batch
2023-03-21T13:10:48-06:00 [Debug] processor: segment batch size: 1. capacity: 50
2023-03-21T13:10:48-06:00 [Info] Successfully sent batch of 1 segments (0.109 seconds)
2023-03-21T13:10:49-06:00 [Debug] Send 1 telemetry record(s)


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

&lt;/div&gt;

&lt;p&gt;It looks like it's working! Let's see the trace in the AWS web console.&lt;/p&gt;

&lt;p&gt;In your AWS web console, go to CloudWatch and in the side panel, look for X-Ray and click on the "traces" option.&lt;/p&gt;

&lt;p&gt;If everything went well, you'll see the number of recently received traces, and the traces table will be populated with such traces.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fypdq6vrwwtjyxgkrgtip.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fypdq6vrwwtjyxgkrgtip.png" alt="Cloudwatch -&amp;gt; X-Ray -&amp;gt; Traces"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the traces table, click in an entry. We'll be taken to the trace view, were we can see the traced information.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw4naiaofcwt49ko8q8mk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw4naiaofcwt49ko8q8mk.png" alt="Simple trace info"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here we can see the trace data. We only are creating a segment and closing it for each call, so we don't have much other data, but we can see the response status code, the time it took for the request to be served, and, of course, the trace map, which for now includes only the client and the service.&lt;/p&gt;

&lt;h4&gt;
  
  
  Creating sub segments
&lt;/h4&gt;

&lt;p&gt;So now that we have our basic instrumentation setup, what else can we trace?&lt;/p&gt;

&lt;p&gt;As of now, we are only tracing a request and some of its metadata. But what if we want to be more granular?&lt;/p&gt;

&lt;p&gt;Let's say we have an intensive process running as part of the request; we can add a subsegment to monitor it.&lt;/p&gt;

&lt;p&gt;Somewhere in my service, the following code is executed when I call the &lt;code&gt;auth/roles&lt;/code&gt; endpoint:&lt;/p&gt;

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

&lt;span class="c"&gt;// inside a function&lt;/span&gt;
&lt;span class="n"&gt;roles&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="nb"&gt;make&lt;/span&gt;&lt;span class="p"&gt;([]&lt;/span&gt;&lt;span class="n"&gt;Role&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rolesList&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;roleItem&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="k"&gt;range&lt;/span&gt; &lt;span class="n"&gt;rolesList&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;role&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;buildRole&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;roleItem&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="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RoleList&lt;/span&gt;&lt;span class="p"&gt;{},&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;roles&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;role&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;We can wrap the &lt;code&gt;for&lt;/code&gt; loop in a subsegment so we can see how much of the request time is spent in this process.&lt;/p&gt;

&lt;p&gt;To add a subsegment, we wrap the loop as:&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;err&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;xray&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Capture&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"BuildRolesDetail"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx1&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="kt"&gt;error&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;roleItem&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="k"&gt;range&lt;/span&gt; &lt;span class="n"&gt;rolesList&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;role&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;buildRole&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;roleItem&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="n"&gt;err&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="n"&gt;roles&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;role&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;xray&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AddMetadata&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"No. roles built"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;roles&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;nepErrors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;InternalServerError&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WithDetail&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;Error&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="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;Let's run our service and call again our instrumented endpoint.&lt;/p&gt;

&lt;p&gt;This is the new trace in AWS CloudWatch -&amp;gt; Traces:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fn6zhgj6gjtux0kgvvh3x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fn6zhgj6gjtux0kgvvh3x.png" alt="Trace with subsegment"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now we see that the request took &lt;strong&gt;215ms&lt;/strong&gt;, and of those, the &lt;code&gt;BuildRolesDetail&lt;/code&gt; loop took &lt;strong&gt;205ms&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;Are you starting to think about the tracing posibilities? You should! You can use &lt;code&gt;xray.AddMetadata&lt;/code&gt; to add any extra information you need. Just take into consideration that X-Ray Daemon only sends to &lt;a href="https://docs.aws.amazon.com/xray/latest/devguide/xray-api-segmentdocuments.html" rel="noopener noreferrer"&gt;AWS up to 64KB of metadata per Segment&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Instrumenting AWS Clients with X-Ray
&lt;/h3&gt;

&lt;p&gt;Instrumenting AWS clients using the SDK-V1 is fairly simple, you can follow the &lt;a href="https://docs.aws.amazon.com/xray/latest/devguide/xray-sdk-go-awssdkclients.html" rel="noopener noreferrer"&gt;official guide&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;There isn't much documentation about how to instrument AWS SDK-v2 clients, but the configuration is also simple.&lt;/p&gt;

&lt;p&gt;Somewhere in your service code, you'll be initializing your AWS client(s). To add instrumentation to them, you just need to provide the clients with an X-Ray HTTP client and pass the request context along for every call.&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;cfg&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LoadDefaultConfig&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="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="c"&gt;// Create an HTTP client&lt;/span&gt;
&lt;span class="n"&gt;httpClient&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;http&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="c"&gt;// Set the HTTP client as the AWS configuration's HTTP client&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;HTTPClient&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;httpClient&lt;/span&gt;

&lt;span class="c"&gt;// Create an X-Ray client&lt;/span&gt;
&lt;span class="n"&gt;xrayClient&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;xray&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="n"&gt;httpClient&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;dynamoClient&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;dynamodb&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewFromConfig&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cfg&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&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;dynamodb&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Options&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c"&gt;// Wrap the http.Client with an xray.Client&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;HTTPClient&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;xrayClient&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;Here, I'm adding the X-Ray HTTP Client to the AWS DynamoDB Client.&lt;/p&gt;

&lt;p&gt;Let's call again our instrumented endpoint.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7hp4dhpe02f048jwo95c.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7hp4dhpe02f048jwo95c.png" alt="Instrumented dynamodb client"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I'm currently running DynamoDB locally, but you can already see how much time is spent per call to DynamoDB. We can also see that the Trace Map has been updated to show my local instance of DynamoDB.&lt;/p&gt;

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

&lt;p&gt;Instrumenting a service with X-Ray is relatively simple, but it can get complex really fast depending on the things we want to monitor. Because of this, the effort to add tracing to your service might vary based on your use case.&lt;/p&gt;

&lt;p&gt;Another thing to consider is the 64KB limit per segment. It might not be enough if you want to trace lots of subsegments or add more metadata. There are ways to circumvent this, but they are out of the scope of this post.&lt;/p&gt;

&lt;p&gt;In conclusion, implementing X-Ray in a Go microservice is a straightforward process that can greatly benefit your application's observability and troubleshooting capabilities. The integration process is relatively easy, and the X-Ray SDK provides a range of useful features that make it easy to trace requests and identify bottlenecks. However, it's important to keep in mind that X-Ray does have some drawbacks, such as the cost associated with using it and the limitations of its sampling capabilities.&lt;/p&gt;

&lt;p&gt;Nonetheless, with careful consideration and proper implementation, X-Ray can be an invaluable tool for debugging and optimizing your microservices architecture. So don't hesitate to give it a try and see how it can enhance the performance and reliability of your Go microservices.&lt;/p&gt;

</description>
      <category>xray</category>
      <category>aws</category>
      <category>go</category>
      <category>instrumentation</category>
    </item>
  </channel>
</rss>
