Building a GoLang API in Lambda

Introduction

In this tutorial we will install Amazon Web Services SAM(Serverless Application Model) for local go api development. This will allow us to test and debug our code without incurring any cost for AWS services. Before we get started you will need to install the aws-sam, docker, and golang. The scope of this tutorial will be limited to macOS and assuming you already have docker and golang installed.

First we will install the aws-sam-cli with brew.

Installing aws-sam-cli

brew install aws-sam-cli

Sam should be installed in the following location:

/usr/local/bin/sam

You can test your installation by running the following command:

sam --version

Initializing our project

Now we have our Lambda(aws-sam) and DynamoDB services installed locally we can start building our project. To begin we will need to initialize a runtime for aws-sam. aws-sam currently supports a big list of runtimes.

  • nodejs
  • nodejs4.3
  • nodejs6.10
  • nodejs8.10
  • java8
  • python2.7
  • python3.6
  • python3.7
  • go1.x
  • dotnetcore1.0
  • dotnetcore2.0
  • dotnetcore2.1
  • ruby2.5
  • Provided

In this case we will be choosing go1.x. Initialization is simple:

sam init --runtime go1.x

This will generate the following folder structure:

.
└── sam-app
    ├── Makefile
    ├── README.md
    ├── hello-world
    │   ├── main.go
    │   └── main_test.go
    └── template.yaml

We will have to make modifications to the Makefile, main.go, and template.yaml.

Lets delete the contents of main.go and add the following code. This will create a api with the endpoint /post and will repeat whatever data we post to it!

package main

import (
        "log"
        "github.com/aws/aws-lambda-go/events"
        "github.com/aws/aws-lambda-go/lambda"
)

func PostData (request events.APIGatewayProxyRequest) (events.APIGatewayProxyResponse, error) {
        log.Print(string(request.Body))

        return events.APIGatewayProxyResponse{
                Body:           string(request.Body),
                StatusCode:     200,
        }, nil
}

func main() {
        lambda.Start(PostData)
}

Next lets update our template.yml file. This is our configuration for the api gateway. Here we can map paths to their respective handlers in our go code.

AWSTemplateFormatVersion : '2010-09-09'
Transform: AWS::Serverless-2016-10-31

Description: An example API written in Golang
Resources:
  ExampleAPI:
    Type: AWS::Serverless::Function
    Properties:
      Runtime: go1.x
      Handler: main
      Events:
        PostData:
          Type: Api
          Properties:
            Path: '/post'
            Method: post

Finally lets change our Makefile to reflect the following changes. This will compile our go code and zip it up for lambda to use. (Note that even though we are on a mac we are building for linux. This is because sam will deploy a linux container.)

build:
    env GOOS=linux GOARCH=amd64 go build -o main hello-world/main.go
    zip -j main.zip main

We can build our go code by running:

make

Once everything is in place we can deploy our api with:

sam local start-api

We can test it is functioning by posting data to http://127.0.0.1:3000/post

Hopefully this tutorial is enough to get you jump started with local lambda development. I would like to add a more polished example app eventually, including building a schema for DynamoDB and adding the code to upload and download data from it. Thanks for reading!

 
comments powered by Disqus