<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Sam Atkins</title>
    <description>The latest articles on Forem by Sam Atkins (@samatkins).</description>
    <link>https://forem.com/samatkins</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%2F92209%2Fb6431644-49b5-4dc0-92b4-1a97b52b36aa.jpeg</url>
      <title>Forem: Sam Atkins</title>
      <link>https://forem.com/samatkins</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/samatkins"/>
    <language>en</language>
    <item>
      <title>Books I Want to Read in 2023</title>
      <dc:creator>Sam Atkins</dc:creator>
      <pubDate>Tue, 03 Jan 2023 17:25:20 +0000</pubDate>
      <link>https://forem.com/samatkins/books-i-want-to-read-in-2023-n4i</link>
      <guid>https://forem.com/samatkins/books-i-want-to-read-in-2023-n4i</guid>
      <description>&lt;p&gt;This year, like last year, I want to read some good software engineering books. These are the ones I currently have on my reading list:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Leading Snowflakes by Oren Ellenbogen&lt;/li&gt;
&lt;li&gt;Modern Software Engineering by Dave Farley&lt;/li&gt;
&lt;li&gt;Building Microservices: Designing Fine-grained Systems by Sam Newman&lt;/li&gt;
&lt;li&gt;Machine Learning Engineering with Python by Andrew P. McMahon&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Which books do you have on your reading list for 2023?&lt;/p&gt;

</description>
      <category>books</category>
      <category>softwareengineering</category>
      <category>engineeringmanagement</category>
    </item>
    <item>
      <title>Go - how to create a JSON body with an array (slice) of maps?</title>
      <dc:creator>Sam Atkins</dc:creator>
      <pubDate>Mon, 19 Apr 2021 19:12:59 +0000</pubDate>
      <link>https://forem.com/samatkins/go-how-to-create-a-json-body-with-an-array-slice-of-maps-174p</link>
      <guid>https://forem.com/samatkins/go-how-to-create-a-json-body-with-an-array-slice-of-maps-174p</guid>
      <description>&lt;p&gt;I'm learning Go and am trying to build a JSON request body of this shape the &lt;code&gt;name&lt;/code&gt; values are created dynamically based on a provided string. The JSON looks like this based on the input string &lt;code&gt;"joan,john"&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"reviewers"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"user"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"joan"&lt;/span&gt;&lt;span class="p"&gt;}},&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"user"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"john"&lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I've searched how to build a slice of maps and have put together the code below but am getting complier errors. Where are am I going wrong?&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;HTTPRequestBody&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;Reviewers&lt;/span&gt; &lt;span class="n"&gt;ReviewersArray&lt;/span&gt; &lt;span class="s"&gt;`json:"reviewers,omitempty"`&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;ReviewersArray&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;Rs&lt;/span&gt; &lt;span class="p"&gt;[]&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;Users&lt;/span&gt; &lt;span class="n"&gt;User&lt;/span&gt;
    &lt;span class="p"&gt;}&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;User&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;User&lt;/span&gt; &lt;span class="n"&gt;Name&lt;/span&gt; &lt;span class="s"&gt;`json:"user`&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;Name&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Name&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="s"&gt;`json:"name`&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;addReviewers&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;reviewers&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;ReviewersArray&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;reviewersSplit&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;reviewers&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;rArray&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;ReviewersArray&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;r&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;reviewersSplit&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;u&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;User&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Name&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;Name&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt;
        &lt;span class="c"&gt;// Error: cannot use u (variable of type *User) as struct{Users User} value in argument to append&lt;/span&gt;
        &lt;span class="n"&gt;rArray&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Rs&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;rArray&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Rs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;u&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;rArray&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;testReviewers&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="s"&gt;"joan,john"&lt;/span&gt;

    &lt;span class="n"&gt;prReviewers&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;addReviewers&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;testReviewers&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;requestBody&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;HTTPRequestBody&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c"&gt;// Error: cannot use prReviewers (variable of type *ReviewersArray) as ReviewersArray value in struct literal&lt;/span&gt;
        &lt;span class="n"&gt;Reviewers&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;prReviewers&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;jsonData&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MarshalIndent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;requestBody&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;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="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;jsonData&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;



</description>
      <category>help</category>
      <category>go</category>
    </item>
    <item>
      <title>Docker Multi-Stage Builds</title>
      <dc:creator>Sam Atkins</dc:creator>
      <pubDate>Sat, 06 Feb 2021 11:04:50 +0000</pubDate>
      <link>https://forem.com/samatkins/docker-multi-stage-builds-omj</link>
      <guid>https://forem.com/samatkins/docker-multi-stage-builds-omj</guid>
      <description>&lt;p&gt;At work, we’re using Docker multi-stage builds to get smaller image sizes. I thought I’d try it out with a small learning project. The headline result is I reduced a Docker image from 305MB to 12.2MB.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# before
docker image ls
helloworldapi latest b24c966e9bgg 6 weeks ago 305MB

# after
docker image ls
helloworldapi latest f1f76e06146h 7 seconds ago 12.2MB

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

&lt;/div&gt;



&lt;h2&gt;
  
  
  Multi-Stage Builds
&lt;/h2&gt;

&lt;p&gt;How do multi-stage builds work? Every instruction i.e. line in a Dockerfile adds a layer to the image. A common practice was to have a development version of your Dockerfile which included everything you needed and a slimmed down version used for production. With multi-stage builds you don’t need to maintain two Dockerfiles. Instead you can use the syntax &lt;code&gt;FROM ... AS &amp;lt;NAME&amp;gt;&lt;/code&gt; to name a stage, and then copy that named stage when you want want to use it. Only what is needed is brought across in this &lt;code&gt;COPY&lt;/code&gt; and all the other layers are discarded. This results in smaller image sizes.&lt;/p&gt;

&lt;p&gt;Here’s an example from the learning &lt;a href="https://github.com/sam-atkins/helloworldapi" rel="noopener noreferrer"&gt;project&lt;/a&gt; I mentioned earlier. This is the Dockerfile before without using multi-stage. The image size was 305MB.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;FROM golang:1.15.5-alpine
WORKDIR /app
COPY . .
RUN go mod download
RUN go build -o main .
CMD ["/app/main"]

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

&lt;/div&gt;



&lt;p&gt;This is the Dockerfile using a multi-stage, named as &lt;code&gt;builder&lt;/code&gt; and used like this &lt;code&gt;COPY --from=builder /app .&lt;/code&gt; i.e. copy the named stage into the &lt;code&gt;/app&lt;/code&gt; directory.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;FROM golang:1.15.5-alpine AS builder
WORKDIR /app
COPY main.go .
RUN go build -o main .

FROM alpine:latest
WORKDIR /app
COPY --from=builder /app .
CMD ["/app/main"]

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

&lt;/div&gt;



&lt;p&gt;As a result of using this multi-stage the image size is now 12.2MB.&lt;/p&gt;

&lt;h2&gt;
  
  
  Named Stages
&lt;/h2&gt;

&lt;p&gt;Stages are not named by default and you can refer to each stage by an integer starting at 0 for the first &lt;code&gt;FROM&lt;/code&gt;. So if the Dockerfile read &lt;code&gt;FROM golang:1.15.5-alpine&lt;/code&gt; we could copy it across like this &lt;code&gt;COPY --from=0 /app .&lt;/code&gt;. I prefer to use names as it makes it more obvious what is happening in the Dockerfile.&lt;/p&gt;

&lt;h2&gt;
  
  
  Target a Stage
&lt;/h2&gt;

&lt;p&gt;How can you use multi-stage builds? When building an image you can target a stage. For example, a build stage named &lt;code&gt;dev&lt;/code&gt; in a Dockerfile would be built like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker build --target dev -t "${DOCKER_REGISTRY}"/${IMAGE_NAME}:"${IMAGE_TAG}-dev" .

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

&lt;/div&gt;



&lt;p&gt;The example above assumes variables are set for the Docker registry where the image is published, the image name and the image tag.&lt;/p&gt;

&lt;p&gt;If the image is published then you can use this in Docker Compose:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;service-name:
 image: $DOCKER_REGISTRY/$IMAGE_NAME:$IMAGE_TAG-dev

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

&lt;/div&gt;



&lt;p&gt;Alternatively, if the Dockerfile and source code are available on your local machine, you can target it like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;service-name:
 build:
 context: path-to-service-name-source-code
 target: dev

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

&lt;/div&gt;



</description>
      <category>docker</category>
      <category>ci</category>
      <category>devops</category>
    </item>
    <item>
      <title>3 Recommended Programming Books</title>
      <dc:creator>Sam Atkins</dc:creator>
      <pubDate>Wed, 23 Jan 2019 09:21:12 +0000</pubDate>
      <link>https://forem.com/samatkins/3-recommended-programming-books-gfk</link>
      <guid>https://forem.com/samatkins/3-recommended-programming-books-gfk</guid>
      <description>&lt;p&gt;As I reflect on 2018, there were three programming books I enjoyed reading and learned a lot from. I thought I would share my summary of each book.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Pragmatic Programmer by Andrew Hunt and David Thomas
&lt;/h3&gt;

&lt;p&gt;Recommended to me by my boss, this is a timeless guide to programming. Programming and technology moves fast, yet despite being written in 1999 this book is still relevant today. In my opinion, the fact this is the case shows just how important the principles the book teaches are. This book really helped me with understanding programming best practices and how I can build those best practices into my daily work. It's a reference to keep coming back to as I progress in my programming career.&lt;/p&gt;

&lt;h3&gt;
  
  
  Coders at Work by Peter Seibel
&lt;/h3&gt;

&lt;p&gt;Another recommendation from my boss, this is a series of interviews with incredible programmers. It is interesting reading about the different approaches these programmers take to their work.&lt;/p&gt;

&lt;p&gt;Of particular interest was reading the contrasting and complementary philosophies and approaches of Brendan Eich and Douglas Crockford when discussing developing the JavaScript language.&lt;/p&gt;

&lt;p&gt;I also enjoyed reading about Brad Fitzpatrick and his incredible blend of programming skills and business/open source acumen with LiveJournal and Memcached as great examples of this.&lt;/p&gt;

&lt;p&gt;And from a broader industry perspective a very topical and important theme, reading about Fran Allen's experience of the how the industry became male dominated and her views on the importance of increasing diversity.&lt;/p&gt;

&lt;h3&gt;
  
  
  The DevOps Handbook by Gene Kim, Jez Humble, Patrick Debois, John Willis
&lt;/h3&gt;

&lt;p&gt;This was probably my favourite programming book I read last year. It's full title is The DevOps Handbook:: How to Create World-Class Agility, Reliability, and Security in Technology Organizations&lt;/p&gt;

&lt;p&gt;My background, prior to switching careers, was in Supply Chain and Operations (in the manufacturing sense) including lean and process optimisation work. This book was a real eye opener, taking a manufacturing operational view to building software. The book explains how a DevOps culture looking at People, Process and Tools can drastically improve a software company's performance, in terms of speed to market and software resilience.&lt;/p&gt;

&lt;p&gt;The insight that infrastructure as code is actually the most important aspect to use version control (rather than as I had previously assumed for development code) was a huge point but once digested makes sense. If you have an interest in DevOps and how teams work to build software, I highly recommend this book.&lt;/p&gt;

</description>
      <category>programming</category>
      <category>books</category>
    </item>
    <item>
      <title>What's new in Python 3.7</title>
      <dc:creator>Sam Atkins</dc:creator>
      <pubDate>Fri, 17 Aug 2018 13:41:30 +0000</pubDate>
      <link>https://forem.com/samatkins/whats-new-in-python-37-2i6f</link>
      <guid>https://forem.com/samatkins/whats-new-in-python-37-2i6f</guid>
      <description>&lt;p&gt;This is an interesting summary of what's new in Python 3.7. I'm particularly excited about types and dataclasses, and &lt;code&gt;breakpoint()&lt;/code&gt; should prove very handy too.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://hackaday.com/2018/07/23/hands-on-with-python-3-7-whats-new-in-the-latest-release/" rel="noopener noreferrer"&gt;https://hackaday.com/2018/07/23/hands-on-with-python-3-7-whats-new-in-the-latest-release/&lt;/a&gt;&lt;/p&gt;

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