Golang and AWS Lambda are two of the primary tools I use everyday for work, so when AWS announced that lambda would natively support Go earlier this year I was ecstatic. In this tutorial, I'll walk through how easy it is to deploy a fully functional API using these technologies and others by way of the serverless framework.

Disclaimer

This tutorial is designed to be deployed to AWS, and while the majority of resources should fall under the free tier, please be aware that this could be costing you actual money.

Some Background

So why is official support for Golang in AWS Lambda so great?

Well, firstly, building a Golang application is dead simple, and this makes deployment dead simple. The output of go build is a statically linked binary, and this is literally the only thing you need to deploy an application to lambda.

Second, Golang enjoys one of the lower cold start times of the currently supported languages, and is likely to improve on that mark in the future.

Also, sometimes you just get tired of javascript.

Setup

Before we get started, we need to prepare our environment. My machine is setup with the following:

In fact, even in this simple form, we are able to deploy the two functions to lambda and test them out. I like to add a new build target to the Makefile to facilitate this. Here's what that looks like:

Our Handler func is being executed on every lambda function invocation, always returning a static response.

Adding an API

Now that we're starting to get a feel for deploying and executing lambda functions with Golang, let's begin to introduce an API. First, we'll need to install some dependencies and remove the aws-lambda-go dependency.

You'll likely receive a warning from dep at this point indicating that the installed dependencies are not imported by your project, but we'll address that soon enough. Let's start by creating a new directory for our handler and removing the demo functions.

Telling that instance to run our foo function when it receives a GET at /foo.

The most interesting part is how we "start the engine". If the environment variable GIN_MODE is set to "release", we wrap our handler with the gateway package, which basically abstracts the API gateway syntax and allows us to focus on the server itself. Cool, right?

If GIN_MODE does not equal "release", we start an ordinary http server.

A few things to note on these changes. In the Makefile, we remove the old calls to go build and introduce a new one for our handler. In serverless.yml, we're again removing references to our previous functions and adding our handler.

The more interesting part is the addition of events. This block tells serverless what events need to take place in order to invoke our Lambda function. In this case, we're saying that we want our function to be invoked in response to API gateway receiving a GET request to /foo.

Be sure to take special care to note the endpoints section of the output. This is the public URL of your API gateway endpoint and should end in /dev/foo. Let's test that endpoint with curl (yours will be different).