April 29, 2019

GoLang - Building APIs Pt.1

Building a basic REST interface in GoLang Part 1. This tutorial will walk through the basic setup of your environment and getting a boilerplate setup.

GoLang - Building APIs Pt.1

In this blog post, I will assume that you are familiar with what REST is and how it works, I will assume that you understand the basics of how HTTP handles requests and that you are familiar with the basic concepts of lower* level languages such as C, C++ etc. If not, I would suggest reading around the following topics:

  • Pointers
  • IO Streams
  • Buffers
Drove around for hours looking for waterfalls and found this gem. If you use this photo, please consider crediting https://www.goodfreephotos.com , not required, but appreciated.
Photo by Good Free Photos / Unsplash

So, now we'll get into the big question which is "Why GoLang?".

The reason I have chosen to do this in GoLang is for several reasons, firstly it is relatively new to the scene, secondly it is blazingly fast at what it does at the network level and thirdly, I struggled when I first picked up GoLang as a language and thought it'd be good to write a few posts on how to use the language.

Ottawa road in the evening
Photo by Marc-Olivier Jodoin / Unsplash

Setting up

The first thing that we need to do to get up and running with GoLang is to setup our environment. I would highly recommend using a Linux machine or Macintosh for this, although it is possible to build GoLang on windows.

First, we need to install Go, the way we do this is to head over to the GoLang website https://golang.org/dl/ and download the relevant binaries/tar gz file onto your machine. Then follow the instructions at https://golang.org/doc/install to learn how to install the application.

Internet modem/ router taken from my office
Photo by Host Sorter / Unsplash

Next, we need to install dep, dep is a package that sits on top of Go and manages the dependencies for a given service[1]. By using dep we can bundle all of our dependencies into the main binary that we distribute.

To install this head over to the dep website and follow the install instructions. Although this can be done on windows, it is not supported yet.

Once we have this installed, we should install an IDE, I recommend Visual Studio Code as it has very good Go bindings, although any text based editor will work.

lost in space
Photo by Martijn Baudoin / Unsplash

Building our boilerplate

So, you've installed Go and Dep, you've loaded up VS Code and you're ready, what now?

The first thing that we need to do is initialise the project, we do this by running

[jamescrocker@host ~]$ mkdir ~/go/src/todo
[jamescrocker@host ~]$ cd ~/go/src/todo
[jamescrocker@host ~/go/src/todo]$ dep init

Yep it's that easy, you've now created your first go project that is dependency managed, congratulations, now what? Well seeing as series is looking at REST interfaces, it'd be rude of me not to show you how to handle a basic GET, wouldn't it?

Check out my instagram page for more pictures like this at https://instagram.com/motivational.coder
Photo by Fabian Grohs / Unsplash

The code file that we need to create in the first instance is called main.go, this is the only file we will create here. We can create this by running.

[jamescrocker@host ~/go/src/todo]$ touch main.go

We then want to populate this with some content, for those who don't want to understand the code, it should look like this

package main

import (
    "net/http"
)

func main() {
    mux := http.NewServeMux()
    
    mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        w.WriteHeader(200)
        w.Write([]byte("Hello World")
        return
    })
    
    http.ListenAndServe("0.0.0.0:3000", mux)
}

Now that we have the code we want to run it, to do this you would run

[jamescrocker@host ~/go/src/todo]$ go run *.go

And now to explain this,

package main

This tells the compiler that the file is part of the main package, this is what is required for the compilation of the binary.

import (
    "net/http"
)

This tells the compiler that we want to use the http package from the Go base library, if we wanted to use a 3rd party library we would have to get this from github.

mux := http.NewServeMux()

This allows us to use server path based routing in the application.

mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
    w.WriteHeader(200)
    w.Write([]byte("Hello World")
    return
})

This tells the mux router how to route the specified request and how to handle it.

http.ListenAndServe("0.0.0.0:3000", mux)

This listens on all interfaces on the port 3000, this also tells the server to use the mux handler for all requests.

Speedcurve Performance Analytics
Photo by Luke Chesser / Unsplash

Summary

In summary we have

  • Setup an environment in which we can write Go code
  • We have setup a dependency manager that allows us to install 3rd party dependencies
  • We have written a basic web server that will return the words "Hello World" upon request

Come back for part 2

[1] You cannot do this for a library, it just doesn't work as you end up with mismatched versions.