February 8, 2018
Under tutorial
, open-source

Learning Go as a Node.js Developer

In the past years, Kubernetes emerged as the go-to container scheduling and management platform. As I'd like to understand better what's happening under the hood, I decided that I'll learn the Go language.

In this article, I'll summarize my learnings from a Node.js developer's point of view. I'll pay particular attention to:

  • dependency management,
  • how asynchronous operations are handled.

Let's get to it :)

What's Go?

Go is an open source programming language that makes it easy to build simple, reliable, and efficient software. - golang.org

Go was created in 2009 at Google by Robert Griesemer, Rob Pike, and Ken Thompson. It is a compiled language, which comes with static types. It has a garbage collector and handles asynchronous operations in a CSP style. Go has a C-like syntax:

package main
import "fmt"
func main() {
fmt.Println("hello world")

Installing Go

To install Go, follow the official setup guide: https://golang.org/doc/install.

Dependency management in Go

As someone who writes a considerable amount of JavaScript code, one of the first questions I had was how does Go handle dependency management? It seems two solutions have emerged:

go get
is shipped with the Go language itself, while
is a dependency manager for Go. In npm terms, you can think of them like this: use
go get
whenever you'd use
npm install -g
, and use
for project specific dependencies.

To get

, you could use
go get
to install it, using:

go get -u github.com/golang/dep/cmd/dep

However, there’s a drawback to using

go get
- it does not handle versions, it just grabs the head of the provided GitHub repository. This is why it is recommended that you install dep using these commands:

brew install dep
brew upgrade dep

(you can read instructions for different OSs here: Go install guide)

Once you have dep installed, you can create projects using

dep init
, just like you would do it with
npm init

Before start developing with Go, take some time to set up the

environment variable correctly - you can use the official Go install guide as a reference.

will create similar files that
would -
to describe the project, just like
in the Node.js ecosystem. The analogy for
, while instead of using the
puts dependencies into the

To add dependencies, you only have to run

dep ensure -add github.com/pkg/errors
. After running it, it will appear both in your lock and your

name = "github.com/pkg/errors"
version = "0.8.0"

Handling asynchronous operations in Go

When writing asynchronous JavaScript, we are used to some libraries/language features, like:

  • the async library,
  • Promises,
  • or
    async functions

Using them, we can easily read files from the file system:

const fs = require("fs");
const async = require("async");
const filesToRead = ["file1", "file2"];
(filePath, callback) => {
fs.readFile(filePath, "utf-8", callback);
(err, results) => {
if (err) {
return console.log(err);

Let's see what it looks like in Go!

package main
import (
func main() {
datFile1, errFile1 := ioutil.ReadFile("file1")
if errFile1 != nil {
datFile2, errFile2 := ioutil.ReadFile("file2")
if errFile2 != nil {
fmt.Print(string(datFile1), string(datFile2))

Let's see what happened in the code snippet above line by line:

  • import
    - with import, you can require packages your applications are built upon, just like
    in Node.js,
  • func main
    - the entry point of our application,
  • ioutil.ReadFile
    - tries to read the file, and returns two values:
    • datFile1
      if the operations were successful,
    • errFile1
      if there was some error,
      • this is your chance to handle the error, or crash the process,
  • fmt.Print
    prints merely the results to the standard output.

The example above works, but reads the files one after each other - time to go asynchronous!

For handling threads, Go has a concept called goroutines. A goroutine is a lightweight thread managed by the Go runtime - it enables you to run Go functions concurrently.

To manage/synchronize goroutines, I ended up using the errgroup package. This package provides synchronization, error propagation, and Context cancellation for groups of goroutines working on subtasks of a common task.


, we can rewrite the file reading code snippet to run concurrently this way:

package main
import (
func readFiles(ctx context.Context, files []string) ([]string, error) {
g, ctx := errgroup.WithContext(ctx)
results := make([]string, len(files))
for i, file := range files {
i, file := i, file
g.Go(func() error {
data, err := ioutil.ReadFile(file)
if err == nil {
results[i] = string(data)
return err
if err := g.Wait(); err != nil {
return nil, err
return results, nil
func main() {
var files = []string{
results, err := readFiles(context.Background(), files)
if err != nil {
fmt.Fprintln(os.Stderr, err)
for _, result := range results {

Building a REST API in Go

In the Node.js space we have a ton of options when it comes to picking a framework for writing HTTP services - Go is no different. After some searching on Google, I chose Gin to start with.

Its interface is similar to Express or Koa, including middleware support, JSON validation and rendering:

package main
import "github.com/gin-gonic/gin"
func main() {
// Creates a router without any middleware by default
r := gin.New()
// By default gin.DefaultWriter = os.Stdout
// Recovery middleware recovers from any panics and writes a 500 if there was one.
r.GET("/ping", func(c *gin.Context) {
c.JSON(200, gin.H{
"message": "pong",
// Listen and serve on

That's how far I've got for now - no production experience, yet. If you feel like that this blog post was useful, and you'd like to learn more on Go, just let me know, and I'll keep publishing what I learn along my journey tackling the Go language.

Further resources

The above content would not have been possible without following articles:

  • The Go Programming Langauge
  • https://peter.bourgon.org/go-best-practices-2016/
  • https://golang.github.io/dep
  • https://blog.golang.org/defer-panic-and-recover
  • https://gobyexample.com
  • https://www.golang-book.com/
Did you like this article? Subscribe to get notified about new ones on engineering management, open-source and the web!
No spam. Ever.