Building a REST API in golang

5 min read.

I’ve been building a side project with a friend and I thought that I would take the time to write down how we built the back-end for it.

Currently, we’re using golang (or Go for short) consuming APIs as well as providing an API. This post will mainly consist of how we did the later part.

To build this API we used web framework called Revel that, not so different from Ruby on Rails and ExpressJS, provides a MVC pattern for building web based applications on.

Setting up Revel

Assuming that you already have Go, Git and Mercurial up and running then there are only two additional things you will need to do to start working with Revel. That is installing the framework and the command line tool.

Installing the Framework

Installing the framework is as easy as running the following command in your terminal

go get github.com/revel/revel

This will clone the revel source from Github into your GOPATH as well as installing the dependencies that Revel has.

Next up the command line tool.

Installing the Command Line Tool

This is as simple as installing the framework. First run

go get github.com/revel/cmd/revel

if everything is working as it should, then you should be able to write the following in your terminal

revel help

If you run into any problems you can find more thorough instructions over at the Revel website.

Creating the project

With the command line tool you can create a new project by using the revel new command. The command takes an import path as a parameter and the last part of the import path will become the name of the application.

Let’s create a new application by running the command below. You can substitute the import path for something that’s better fitting for you.

revel new your/import/path

this will create a revel project under GOPATH/src/your/import/path.

You can now start the application by running revel run your/import/path. If you go to localhost:9000 in your browser you should now see the revel default page.

Adding some code

Now that we have a project setup, lets start building the API. In this example app we will build an Beer API which will have a beer resource. The idea is that when you visit /beers a list with beers will be outputted in JSON. We will also handle displaying individual beers.

For doing this we will need to create a model, a controller and then we need to configure a route for incoming requests. Lets start with the Model.

Adding a Model

Lets start by adding a new file with the following name and path app/models/beer.go

In this file we will add the new struct with the basic properties name, type and brewery to represent our beer model.

package models

type Beer struct {
	ID      int
	Name    string
	Type    string
	Brewery string
}

In a real application we would most likely use some sort of database in conjunction with the models. However, for this example I will omit it and just use mock data. So lets get started on that within the controller.

Adding a controller

Add a new controller called beers.go, to app/controllers in the project folder and add the following code

package controllers

import (
	"github.com/revel/revel"
	"your/import/path/app/models"
)

type Beers struct {
	*revel.Controller
}

By doing this we are creating a Beer struct which inherits properties from the revel.Controller struct. We are also importing the necessary packages that will be used in this controller. Let continue setting up a function for displaying lists of beers.

var beers = []models.Beer{
	models.Beer{1, "La Trappe Quadrupel Oak Aged", "Ale", "Bierbrouwerij De Koningshoeven"},
	models.Beer{2, "Cocoa Psycho", "Porter", "BrewDog"},
	models.Beer{3, "American Dream", "Lager", "Mikkeller"},
}

func (c Beers) List() revel.Result {
	return c.RenderJson(beers)
}

Here we are creating a member variable containing an array of beers, using the Beer model we created earlier. In the function we are then telling the Revel Controller to render this as JSON.

As I wrote earlier we will also make it possible to view each individual beer. Lets make this possible by adding the following function to the controller.

func (c Beers) Show(beerID int) revel.Result {
	var res models.Beer

	for _, beer := range beers {
		if beer.ID == beerID {
			res = beer
		}
	}

	if res.ID == 0 {
		return c.NotFound("Could not find beer")
	}

	return c.RenderJson(res)
}

Using a for-loop we can iterate over the list of beers and if the id of the beer matches the beerID provided in the request we can render the beer. Otherwise we render a 404.

Now that the model and the controller is setup we will have to setup the routing for the API.

Setting up the routing

Now we need to hook up the controller with the incoming requests. We want is to display the beer list under /beers and to display each individual beer under /beers/[id].

To do this we will need to configure the routing in conf/routes. In this file we can map resource paths and HTTP Methods with different controllers and functions. In the file you should already see the following line

GET     /                                       App.Index

What this means is that all incoming GET requests to the / path should be controlled by the App controllers Index function.

Now add the following below the line mentioned above.

GET     /beers                                  Beers.List
GET     /beers/:beerID                          Beers.Show

This maps the /beers path to the List function and the /beers/:beerID path to the Show function. Notice that :beerID is what we use in the Show function filter out the correct beer to display.

Now, if you start the application using the command revel run your/import/path you should be able to see the API in action.

Update: Thomas Jaensch commented on a typo in the code example above. It has now been fixed. Also checkout Thomas code example.

comments powered by Disqus