Building a REST Service with Golang - Part 1 (Setup)

Intro

Golang is pretty hot right now. Over the past few weeks, I've been exploring implementing some of the cloud infrastracture I'd previously built with node in go, partly for fun, partly because go is fast. This led me to believe that setting up a basic REST service would make for a great tutorial.

At the end, we will have a fully functioning REST service for serving basic CRUD on a user resource. Code for the final product can be found here.

This is the first in a series of high level tutorials on setting up a REST service using golang, focused on getting a go dev environment setup.

Setup

The first step to start rocking some go is to get it installed. Being a mac user, I initially installed go globally with brew, but then reverted to using gvm, as I love the flexibility I get with its node counterpart, nvm.

Here we go:

# Install gvm
$ bash < <(curl -s -S -L https://raw.githubusercontent.com/moovweb/gvm/master/binscripts/gvm-installer)

# Install the latest go version (as of this writing)
$ gvm install go1.4

# Set it as active, and the default choice
$ gvm use go1.4 --default

Done.

So now we have a local version of go installed, our GOPATH and PATH are setup, and we have access to the go executable. Now what? One of the neat things about gvm is the notion of pkgsets, basically allowing you to define separate "workspaces" and group a set of go projects using the same go version.

Let's create a pkgset called "work".

# Create the pkgset
$ gvm pkgset create work

# Set it as active, and the default choice
$ gvm pkgset use work --default

Sweet. Now, if we inspect our GOPATH and PATH, we can see that they have been updated to reflect our pkgset location. But what if we don't want to work in ~/.gvm/pkgsets/go1.4/work/? Let's setup a directory for our code, say ~/src/go.

# Or something else
$ mkdir -p ~/src/go/{bin,pkg,src}

Now that we have the proper folder structure for go, we'll need to update our environment. We could manually set GOPATH and PATH to be prefixed with our new src directory, but there's a better way. We'll use the gvm pkgenv command with our fresh work pkgset so that our new workspace will always be found in GOPATH.

Enter the following to pull open the environment variables for the work pkgset. We'll be changing the GOPATH and PATH variables to look at ~/src/go. Obviously, adjust your entries to reflect the directory structure on your machine.

# Pull open the environment in our favoriate editor
$ gvm pkgenv work
export GVM_ROOT; GVM_ROOT="/Users/swhite/.gvm"
export gvm_go_name; gvm_go_name="go1.4"
export gvm_pkgset_name; gvm_pkgset_name="global"
export GOROOT; GOROOT="$GVM_ROOT/gos/go1.4"
export GOPATH; GOPATH="$GVM_ROOT/pkgsets/go1.4/global"
export GVM_OVERLAY_PREFIX; GVM_OVERLAY_PREFIX="${GVM_ROOT}/pkgsets/go1.4/global/overlay"
export PATH; PATH="${GVM_ROOT}/pkgsets/go1.4/global/bin:${GVM_ROOT}/gos/go1.4/bin:${GVM_OVERLAY_PREFIX}/bin:${GVM_ROOT}/bin:${PATH}"
export LD_LIBRARY_PATH; LD_LIBRARY_PATH="${GVM_OVERLAY_PREFIX}/lib:${LD_LIBRARY_PATH}"
export DYLD_LIBRARY_PATH; DYLD_LIBRARY_PATH="${GVM_OVERLAY_PREFIX}/lib:${DYLD_LIBRARY_PATH}"
export PKG_CONFIG_PATH; PKG_CONFIG_PATH="${GVM_OVERLAY_PREFIX}/lib/pkgconfig:${PKG_CONFIG_PATH}"
export gvm_pkgset_name="blog"

# Prefix with our go path we created
export GOPATH; GOPATH="$HOME/src/go:/Users/swhite/.gvm/pkgsets/go1.4/blog:$GOPATH"

# Prefix with the bin directory in our gopath
export PATH; PATH="$HOME/src/go/bin:/Users/swhite/.gvm/pkgsets/go1.4/blog/bin:$PATH"

# Package Set-Specific Overrides
export GVM_OVERLAY_PREFIX; GVM_OVERLAY_PREFIX="${GVM_ROOT}/pkgsets/go1.4/blog/overlay"
export PATH; PATH="/Users/swhite/.gvm/pkgsets/go1.4/blog/bin:${GVM_OVERLAY_PREFIX}/bin:${PATH}"
export LD_LIBRARY_PATH; LD_LIBRARY_PATH="${GVM_OVERLAY_PREFIX}/lib:${LD_LIBRARY_PATH}"
export DYLD_LIBRARY_PATH; DYLD_LIBRARY_PATH="${GVM_OVERLAY_PREFIX}/lib:${DYLD_LIBRARY_PATH}"
export PKG_CONFIG_PATH; PKG_CONFIG_PATH="${GVM_OVERLAY_PREFIX}/lib/pkgconfig:${PKG_CONFIG_PATH}"

So now we can re-use our pkgset and our environment will be nice and reasonable.

$ gvm pkgset use work

Test it out

Let's throw together a package to verify our environment it setup properly. First create a folder in the ~/src/go/src directory to house our code. Let's simply call it test.

$ mkdir ~/src/go/src/test
$ cd ~/src/go/src/test

As far as editors are concerned, I ordinarily go for Sublime Text, but have recently been hacking with Atom. When writing go code, I highly recommend the go-plus package.

Now, let's run the canonical intro program. Add the following to test.go.

package main

import "fmt"

func main() {
	fmt.Println("Hello, Gopher!")
}

We can run the program with the following.

$ go run test.go
Hello, Gopher!

Fin

That's the end of the introductory tutorial on building a REST service with golang. We've setup a proper go dev environment and have built a simple go program. Next we'll learn about using third party packages and setting up a basic webserver. Check it out.

Resources