Starter code for writing web services in Go


Ultimate Service


Copyright 2018, 2019, 2020, 2021, Ardan Labs
[email protected]

Ultimate Service 2.0 Video

If you are watching the Ultimate Service video on the ArdanLabs education site, please use this branch in the repo.

This branch represents the code that is explained. I will be going back into the studio in March, 2021 to re-record the video for all the changes in the past year.

Ultimate Service 2.1 Live Classes

This class teaches how to build production-level services in Go leveraging the power of Kubernetes. From the beginning, you will pair program with the instructor walking through the design philosophies and guidelines for building services in Go. With each new feature that is added to the service, you will learn how to deploy to and manage the Kubernetes environment used to run the service.

Course Outline | Class Schedule


Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
See the License for the specific language governing permissions and
limitations under the License.

About The Project

Please read the project wiki.

Learn More

To learn about Corporate training events, options and special pricing please contact:

William Kennedy
ArdanLabs (
[email protected]

Purchase Video

The entire training class has been recorded to be made available to those who can't have the class taught at their company or who can't attend a conference. This is the entire class material.

Our Experience

We have taught Go to thousands of developers all around the world since 2014. There is no other company that has been doing it longer and our material has proven to help jump-start developers 6 to 12 months ahead of their knowledge of Go. We know what knowledge developers need in order to be productive and efficient when writing software in Go.

Our classes are perfect for intermediate-level developers who have at least a few months to years of experience writing code in Go. Our classes provide a very deep knowledge of the programming langauge with a big push on language mechanics, design philosophies and guidelines. We focus on teaching how to write code with a priority on consistency, integrity, readability and simplicity. We cover a lot about “if performance matters” with a focus on mechanical sympathy, data oriented design, decoupling and writing/debugging production software.

Our Teachers

William Kennedy (@goinggodotnet)

William Kennedy is a managing partner at Ardan Labs in Miami, Florida. Ardan Labs is a high-performance development and training firm working with startups and fortune 500 companies. He is also a co-author of the book Go in Action, the author of the blog GoingGo.Net, and a founding member of GoBridge which is working to increase Go adoption through diversity.

Video Training
Ultimate Go Video
Ardan Labs YouTube Channel

Going Go

Running MongoDB Queries Concurrently With Go
Go In Action

IT World Canada

GDN Event #1 (2021) - GoBridge Needs Your Help
Training Within The Go Community (2019)
GopherCon Australia (2019) - Modules
Golab (2019) - You Want To Build a Web Service?
GopherCon Singapore (2019) - Garbage Collection Semantics
GopherCon India (2019) - Channel Semantics
GoWayFest Minsk (2018) - Profiling Web Apps
GopherChina (2018) - Composition In Go William
GopherCon Singapore (2018) - Optimizing For Correctness
GopherCon India (2018) - What is the Legacy You Are Leaving Behind
Code::Dive (2017) - Optimizing For Correctness
Code::Dive (2017) - Go: Concurrency Design
dotGo (2017) - Behavior Of Channels
GopherCon Singapore (2017) - Escape Analysis
Capital Go (2017) - Concurrency Design
GopherCon India (2017) - Package Oriented Design
GopherCon India (2015) - Go In Action
GolangUK (2016) - Dependency Management
GothamGo (2015) - Error Handling in Go
GopherCon (2014) - Building an analytics engine

Practical Understanding Of Scheduler Semantics (2021)
Go Generics Draft Proposal (2020)
Hack Potsdam (2017) - Tech Talk with William Kennedy
Chicago Meetup (2016) - An Evening
Vancouver Meetup (2016) - Go Talk & Ask Me Anything With William Kennedy
Vancouver Meetup (2015) - Compiler Optimizations in Go
Bangalore Meetup (2015) - OOP in Go
GoSF Meetup - The Nature of Constants in Go
London Meetup - Mechanical Sympathy
Vancouver Meetup - Decoupling From Change

Ardan Labs Podcast: On Going Series
GoTime: Learning and Teaching Go
GoTime: Bill Kennedy on Mechanical Sympathy
GoTime: Discussing Imposter Syndrome
HelloTechPros: Your Tech Interviews are Scaring Away Brilliant People
HelloTechPros: The 4 Cornerstones of Writing Software

More About Go

Go is an open source programming language that makes it easy to build simple, reliable, and efficient software. Although it borrows ideas from existing languages, it has a unique and simple nature that make Go programs different in character from programs written in other languages. It balances the capabilities of a low-level systems language with some high-level features you see in modern languages today. This creates a programming environment that allows you to be incredibly productive, performant and fully in control; in Go, you can write less code and do so much more.

Go is the fusion of performance and productivity wrapped in a language that software developers can learn, use and understand. Go is not C, yet we have many of the benefits of C with the benefits of higher level programming languages.

The Why of Go - Carmen Andoh
Go Ten Years and Climbing - Rob Pike
The eigenvector of "Why we moved from language X to language Y" - Erik Bernhardsson
Learn More - Go Team
Simplicity is Complicated - Rob Pike
Getting Started In Go - Aarti Parikh

Minimal Qualified Student

The material has been designed to be taught in a classroom environment. The code is well commented but missing some of the contextual concepts and ideas that will be covered in class. Students with the following minimal background will get the most out of the class.

  • Studied CS in school or has a minimum of two years of experience programming full time professionally.
  • Familiar with structural and object oriented programming styles.
  • Has worked with arrays, lists, queues and stacks.
  • Understands processes, threads and synchronization at a high level.
  • Operating Systems
    • Has worked with a command shell.
    • Knows how to maneuver around the file system.
    • Understands what environment variables are.

Important Reading

Please check out this page of important reading. You will find articles and videos around topics related to this repo.

Before You Come To Class

The following is a set of tasks that can be done prior to showing up for class. We will also do this in class if anyone has not completed it. However, the more attendees that complete this ahead of time the more time we have to cover additional training material.

Prep Work

Reading Material



Joining the Go Slack Community

We use a slack channel to share links, code, and examples during the training. This is free. This is also the same slack community you will use after training to ask for help and interact with may Go experts around the world in the community.

  1. Using the following link, fill out your name and email address:
  2. Check your email, and follow the link to the slack application.
  3. Join the training channel by clicking on this link:
  4. Click the “Join Channel” button at the bottom of the screen.

Installing Go

Local Installation


Visual Studio Code



Installing the Training Material

While many of the examples can be done using the online playground (, some may find it easier to complete them with their local editor. To do so, you will want to load the training material locally to your machine. From a command prompt, issue the following commands:

mkdir -p $(go env GOPATH)/src/ && cd $_
git clone

NOTE: This assumes you have Git installed. If you don’t, you can find the installation instructions here:


Jessie Frazelle (@frazelledazzell)
"@goinggodotnet you were amazing!!! So enthusiastic!!! Thanks for doing this for everyone!"

Kelsey Hightower (‏@kelseyhightower)
"Day 1 of the [Ultimate] Go workshop was outstanding! Big shoutout to @intel, @golangbridge, and @goinggodotnet for bringing this to Portland."

Katrina Owen (@kytrinyx)
"OH: "You thought you knew Go..." (You do Go? You want to do Go?) You should take this workshop. Seriously.) "

Ian Molee (@ianfoo) "If you're at @GopherCon, get yourself to a session with @goinggodotnet. Superb! Pretty sure his pic appears with the definition of "dynamo.""

Matt Oswalt (@Mierdin)
"Should be mentioned that though I am no expert, I have been using Go for about a year - and this meetup is kicking my ass."


Paul Yeoh
_"Today’s workshop was just mind blowing! You kept us all on the edge all day long - it was the most exhilarating all day workshop I have attended, period. The content was inspiring, moving - caused me to think deeply and gave me a lot of meat to chew on about what it is we are really doing as programmers, what an awesome day!

And most of all, I just got such a kick out of the energy which you were putting out - larger than life, it felt like you were turned up to 200%. I really took a lot from it at many levels. Thank you!!"_

Ana-Maria Lazar, Software Engineer at Sainsbury's
"Intensive crash course in Go that literally takes you to a whole new level. Not only Bill provides lots of examples and exercises to familiarize yourself faster with the language but there is also a lot of information that can be applied to other languages as well. Perfect combination!"

Susan Dady, Software Engineer - GE Digital
"Rarely will you come across a course as worthwhile as this one. I learned many things relevant and useful in my daily work and William's energy kept me engaged. I came back to work excited to get coding in Go."

Richard Stanley, Software Engineer - GE Digital
"Not only does Bill deeply understands the technical details of Go, he also can explain them in an effective, enthusiastic manner that helped me retain somewhat dry material. His passion for the language and its capabilities are obvious through out his training."

Shalab Goel, Ph.D.
"It was a pleasure taking this course — learning lot of "dry" stuff in such animated and enthusiastic environment. The exercises were spot on for building what you called as "memory muscle. I have good amount of background in conventional multithreaded and distributed environments, but I have not put that knowledge to use more recently; so it was good refresher from that point of view as well. From Yuck to completely Wow-ed is how I will like to describe my respect for Go within three days. I knew nothing about GO before the course."

Geoff Clitheroe (@gclitheroe)
"Your training is awesome! Myself and three colleagues recently caught variations of the training at GopherCon and OSCON. We all thought the Bootcamp was the best thing at any of these conferences (and I went to both). Awesome work to Bill for presenting and anyone involved in developing the training. I really liked the structure, emphasis on deeper understanding, me doing a small number of examples to emphasize this, and general content. Night and day to other training which is to often just watching someone else live code. Great work."

ACL Services (@ACLServices)
"I'd just like to thank you again for just a phenomenal training session. The feedback from everyone was overwhelmingly positive. You probably could tell first hand that there were skeptics at first, but you've turned many into golang converts and we are really excited in growing golang adoption internally."

Joshua Shuster (@naysaier)
"I would consider Ardan Studio's 3 day course to be invaluable. Bill and his staff, being some of the foremost authorities in the Go language, were able to make many of the complex go topics understandable. Covering everything from memory management, all the way up to building concurrency programs and web API's. It has given me the knowledge to write idiomatic Go, and make the best use of its features. I would highly their courses to anyone new to Go, or to anyone wanting to widen their existing knowledge."

Neeru Dwivedi
"I attended the one day workshop by Bill Kennedy from Ardan Labs. I was in for a surprise as before the workshop I was concerned whether I would understand concepts and whether I would be able to follow along. Bill has this wonderful way of explaining concepts and his knowledge on the concepts is so good that, I didn't feel that I was learning something new & complicated. The Go Workshop got me started on the Go language. This workshop is perfect for beginners and anyone who wants to learn more about Go. I highly recommend this."

Todd Rafferty (@webrat)
"I highly recommend William Kennedy / Ardan Lab for Go Training. William is extremely passionate about the Go language and his energy feeds into his training. Very professional, very informative. My favorite section of his training, if I had to pick, was the segment on MultiWriters. I highly recommend a 3 day course, over a 2 day course. Even after the classes were over, William was always responsive with additional questions via various social media channels."

Georgi Knox (@GeorgiCodes)
"The Intro to Go Workshop enabled me to come into class with very little knowledge of Go and leave having a firm grasp of the key concepts of the language. Each topic was followed up with hands-on coding problems which helped to solidify what I was learning. My teacher Bill was not only approachable, but very excited about the language and his enthusiasm was contagious. I enjoyed that we talked about some of the lower level implementation details of Go which was something that I had found lacking from some books on the language. Overall I would highly recommend this workshop to anyone looking to learn Go quickly and effectively."

All material is licensed under the Apache License Version 2.0, January 2004.

  • Consider cleaning up the .git folder to reduce the repo size

    Consider cleaning up the .git folder to reduce the repo size

    A fresh clone currently takes a good amount of time because of binary files in the commit history.

    You can identify them by running this oneliner: git rev-list --objects --all | grep -f <(git verify-pack -v .git/objects/pack/*.idx| sort -k 3 -n | cut -f 1 -d " " | tail -10)

    1930a9b3151f0dd2b3ff245b9f77fb83407ede70 cmd/search/search
    728a7a93403083b8fd06accde6c79d6ed8cd82a4 cmd/search/search
    41265c8f26433009e979fa88ca50fa5395dc734a cmd/sidecar/metrics/metrics
    8ba505fcf5bad430d4e3e7df1a9b38802260c9a2 cmd/sidecar/metrics/metrics
    90a30e0e48d378088c3a594688da3b5a2b785ce3 cmd/sidecar/metrics/metrics
    e82d16d2e603ec8b6f58aef127d871331c150306 cmd/crud/crud
    97e1a3e5cf9b86726d960fb30d8cf05189cb681b cmd/crud/crud
    fc933685fe478c4686f4733e4f8d01242906cc1e cmd/crud/crud
    218ad79408ee5e4e2f71748ecccfc8e1d4f54133 cmd/crud/crud
    099217f9bae311d3159d43af64e2ccac8076d315 cmd/crud/crud

    Filename Git id

    crud | 218ad794 (7,6 MB), 099217f9 (7,6 MB), ...
    metrics | 90a30e0e (5,8 MB), 8ba505fc (6,2 MB), 41265c8f (6,2 MB) search | 1930a9b3 (11,8 MB), 728a7a93 (12,4 MB)

    opened by tullo 37
  • Graceful terminations within Kubernetes

    Graceful terminations within Kubernetes

    Noticed during a rolling update that communication to the Pod was briefly disrupted. After some digging found this discussion: which highlights the race condition between the app closing the listener and Kubernetes actually disallowing connections to go to the service.

    Shutdown line here for reference:

    Assuming that this is indeed the root cause, we should implement one of the three approaches listed in the linked issue.

    Additionally, looking through the linked blog post in the issue ( they reference removing keep-alive connections towards the bottom which seems can be controlled via:

    opened by jpreese 25
  • question: is there a reason we don't log the actual response?

    question: is there a reason we don't log the actual response?

    I think, same as the response code, we can also add the actual response to the context and log it, is there any concern/reason we are not doing it?

    if not, please let me PR in 😄

    opened by mrkagelui 17
  • sales-admin data model validation

    sales-admin data model validation

    Model validation currently happens within the web package through the .Decode function. This means that data that is added through the admin CLI won't go through the same validation checks. For example, attempting to add an email of "a" would fail through the HTTP handler, but would work if typed into the command line.

    Since both of these scenarios are accepting user input which we do not have much control over, it feels like there should be some validation checks in the CLI as well. Thoughts?

    opened by jpreese 15
  • Use declarative configuration struct in main

    Use declarative configuration struct in main

    Example for #16. This PR uses an anonymous type in main as a form of making configuration more declarative. IMO this makes configuration inputs more searchable. Possible benefits include: easy exposure of configuration via a future API endpoint along with the ability to print configuration usage. The envconfig package is used as reference implementation... it would probably be replaced with a kit package.

    opened by nstogner 12
  • K8s : Supprt for MiniKube and Skaffold

    K8s : Supprt for MiniKube and Skaffold

    Skaffold is a tool that makes developing applications for kubernetes easier. It supports a live-reload development mode where it watches for changes to code and will trigger docker builds / kubectl apply's (really handy when using minikube during local development). It also can be used to simplify build/deploy pipelines. Check it out:

    opened by nstogner 11
  • fix - use shutdown error in authorize when claims are missing

    fix - use shutdown error in authorize when claims are missing

    Forgive me if I'm wrong but in the context of your application I think missing claims in the authorize middleware should return a shutdown error as this should only ever be called if we have been successfully authenticated first?

    opened by kinluek 10
  • Proposal to move authorization logic from `data/store` to `core`.

    Proposal to move authorization logic from `data/store` to `core`.

    Hi Bill!

    I have a suggestion regarding the recently added core package in the business layer.

    I think it's great to have an extra layer between handlers and the data/store. Before, I would find myself adding "business-like" logic inside the handlers. So having the new core cleans up things quite a bit for me.

    However, the new core package helped me with one more thing: cleaning up the layer below (data/store) from similar "business-like" logic.

    For the starter service, the authorization is pretty simple, often involving a RoleAdmin check and/or entity_author vs claims.Subject check. In my own work, authorization has usually been more complex, often involving checks across different entities and also calls to third-party services, before a record is finally "committed" to the database.

    In my case moving such authorization logic from data/store to core made more sense, so I wanted to ask you if you would consider such a change for the starter service too.

    In my view it feels cleaner to keep the data/store as "dumb" as possible, since the scope of most requests ends at this point, with a modified repository record. Such logic would then be moved in the new Pre-Business Operations spots of their core counterparts.

    As a further argument, consider the data/store/Update() method. The first two validate.Checks are clearly linked with what happens next. But the authorization happening at lines ~70-78 could involve checks that are very unrelated to the scope/responsibility of this method (i.e. checks if you're also an admin in a 3rd party service).

    What do you think, does it make sense to move that (and other auth-related checks) in core instead?

    Thanks & have an awesome day, Ciprian

    opened by cip8 9
  • Question: How to get the Search UI served?

    Question: How to get the Search UI served?

    Hi Bill,

    On the search branch I bootstrapped the services with make up and browsing the health endpoint works fine using

    But what endpoint to hit for getting the search.html displayed?

    cmd/search/internal/handlers/routes.go shows that /static/ is stripped away from the path, so my guess is that should serve the UI but I currently get 404 for that. Same for

    SEARCH : 2020/02/20 17:28:00.746631 main.go:78: main : Started : Application Initializing version "c391787a78543663191e11e4f555e02c9f3e55a7"
    SEARCH : 2020/02/20 17:28:00.746709 main.go:85: main : Config :
    SEARCH : 2020/02/20 17:28:00.746726 main.go:102: main : Started : Initializing zipkin tracing support
    SEARCH : 2020/02/20 17:28:00.746831 main.go:95: main : Debug Listening
    SEARCH : 2020/02/20 17:28:00.747080 main.go:150: main : API Listening
    SEARCH : 2020/02/20 17:31:59.074752 logger.go:34: d3d41c829cb0d6ea83aed5b97bc624e9 : (500) : GET /search -> (1.299281ms)
    SEARCH : 2020/02/20 20:10:29.941274 logger.go:34: 7761c6e16a413deb561770312fb6877d : (200) : GET /health -> (33.701µs)
    opened by tullo 9
  • Initial 'make' fails b/c of missing private.pem

    Initial 'make' fails b/c of missing private.pem

    Initial make fails with:

    Step 10/27 : COPY private.pem private.pem
    COPY failed: stat /var/lib/docker/tmp/docker-builder401590106/private.pem: no such file or directory
    makefile:20: recipe for target 'sales-api' failed

    Steps to reproduce:

    1. git clone --depth 1
    2. cd service/ && make
    opened by tullo 9
  • Docker Change Proposal

    Docker Change Proposal

    My first proposal is that the dockerfiles be moved out of the root. We can get away with it with only 3 services, but the more services you have the messier the root is going to be.

    I have a suggestion on how I would structure it, drawn inspiration from previous client projects and my own personal projects:


    I've ommitted a decent amount of file structure above, but that should be enough to see what I'm proposing. The deploy folder can be found in each program's directory. The deploy folder contains the Dockerfile (most important) and maybe some documentation related to the service/environment needed for deployment (examples being apiary.apib and

    Current the compose file is fine the way it is, the Dockerfiles would, however, have to be changed. I like the idea behind using a container to not only run the program, but also build it. Makes deployment even more trivial. I normally do not do this. I normally build the binary and only use docker to host it, automated through makefile rules, and link the containers in a network through compose. This Dockerfiles really easy to read, trivial, and fast. In order to keep building the way they are currently built, you'll have to make minor modifications to the Dockerfiles and build from the root, allowing the build context to be in a place where it can properly copy all the files.

    My second proposal is pretty simple, make a dockerignore and clean up the COPY commands. I noticed we were blindly copying the entire contents of the project into each image to build. We really only need the module files, internal/ and the specific cmd/ subfolder for the requested service.

    question proposal 
    opened by george-e-shaw-iv 9
Ardan Labs
Ardan Labs
A code generator that turns plain old Go services into RPC-enabled (micro)services with robust HTTP APIs.

Frodo is a code generator and runtime library that helps you write RPC-enabled (micro) services and APIs.

Monadic 22 Dec 16, 2022
A starter repo for VS Code, Gitpod, etc for Go.

go-starter After using this template: Replace in go.mod after using this template. Replace go-starter in .gitignore wi

Matt Welke 0 Nov 26, 2021
The starter code for Module 3: Surfstore

Surfstore This is the starter code for Module 3: Surfstore. Before you get start

null 0 Feb 13, 2022
A microservice gateway developed based on golang.With a variety of plug-ins which can be expanded by itself, plug and play. what's more,it can quickly help enterprises manage API services and improve the stability and security of API services.

Goku API gateway is a microservice gateway developed based on golang. It can achieve the purposes of high-performance HTTP API forwarding, multi tenant management, API access control, etc. it has a powerful custom plug-in system, which can be expanded by itself, and can quickly help enterprises manage API services and improve the stability and security of API services.

Eolink 378 Dec 29, 2022
Services-inoeg - The Kiebitz Backend Services. Still a work-in-progess, use with care!

Kiebitz Services This repository contains Kiebitz's backend services: A storage service that stores encrypted user & operator settings and temporary d

Kiebitz! 0 Jan 19, 2022
An opinionated Microservice starter in Go

Go Microservice Starter An opinionated Microservice starter in Go Usage Checkout the code. TLDR; Start the service: docker build -t go-microservice-st

Abhisek Datta 1 Oct 25, 2021
Kyoto starter project

kyoto starter Quick Start project setup What's included kyoto kyoto uikit tailwindcss How to use Clone project with git clone

Yurii Zinets 1 Apr 10, 2022
Astro Starter Kit: Docs Site

Astro Starter Kit: Docs Site npm init astro -- --template docs Features ✅ Full Markdown support ✅ Responsive mobile-friendly design ✅ Sidebar navigat

Connor McCutcheon 2 Apr 10, 2022
GCP Cloud Functions ready to Go starter with hot reload 🔥

GCP Cloud Functions - Go Starter Features: funcFramework already set up - ready for local development and testing. Hot Reload ready-to-go thanks to th

Eric Crescioni 0 Dec 16, 2021
Hackpack-go: A starter pack for hacking in go

hackpack-go This repository is a starter pack for hacking in go Slides https://d

Allen Kaplan 4 Apr 14, 2022
GoLang utility packages to assist with the development of web micro-services.

GoTil Golang utility packages to assist with the development of web micro-services. Installation As a library. go get Usage

Christopher Thomas 0 Nov 26, 2021
Flamingops - Handle your web services consommation with golang

How to use this repo as a template for your project I - Introduction This reposi

Alexandre Delaloy 2 Mar 31, 2022
RPC explained by writing simple RPC framework in 300 lines of pure Golang.

Simple GoRPC Learning RPC basic building blocks by building a simple RPC framework in Golang from scratch. RPC In Simple Term Service A wants to call

Ankur Anand 546 Dec 17, 2022
Sample full stack micro services application built using the go-Micro framework.

goTemp goTemp is a full stack Golang microservices sample application built using go-micro. The application is built as a series of services that prov

null 66 Dec 26, 2022
Connect, secure, control, and observe services.

Istio An open platform to connect, manage, and secure microservices. For in-depth information about how to use Istio, visit To ask questions

Istio 32.2k Jan 9, 2023
Automatic Service Mesh and RPC generation for Go micro services, it's a humble alternative to gRPC with Istio.

Mesh RPC MeshRPC provides automatic Service Mesh and RPC generation for Go micro services, it's a humble alternative to gRPC with Istio. In a nutshell

AstraNet Toolkit 69 Aug 22, 2022
a microservice framework for rapid development of micro services in Go with rich eco-system

中文版README Go-Chassis is a microservice framework for rapid development of microservices in Go. it focus on helping developer to deliver cloud native a

null 2.6k Dec 27, 2022
Dubbo2istio watches Dubbo ZooKeeper registry and synchronize all the dubbo services to Istio.

Dubbo2Istio Dubbo2istio 将 Dubbo ZooKeeper 服务注册表中的 Dubbo 服务自动同步到 Istio 服务网格中。 Aeraki 根据 Dubbo 服务信息和用户设置的路由规则生成数据面相关的配置,通过 Istio 下发给数据面 Envoy 中的 Dubbo p

Aeraki 33 Dec 1, 2022
This tool generates Go language bindings of services in protobuf definition files for go-kit

protoc-gen-go-kit This tool generates Go language bindings of services in protobuf definition files for go-kit. Installation $ go install

X64FUN 1 Nov 9, 2021