Serverless Framework example for Golang and Lambda
Tags: go, lambda, serverless, serverlessframework
Published: 2022-03-28 14:50:44

Originally posted at [Serverless](https://www.serverless.com/blog/framework-example-golang-lambda-support/)

Here’s how you can start using Go with the Serverless Framework RIGHT NOW and deploy Lambdas to your heart’s content.

### Get Started

First things first, you’ll be needing the [Serverless Framework](https://serverless.com/framework/docs/providers/aws/guide/quick-start/) installed, and an [AWS account](http://docs.aws.amazon.com/lambda/latest/dg/setting-up.html#setting-up-signup).

(If it’s your first time using the Serverless Framework, our [first time deployment post](https://serverless.com/blog/anatomy-of-a-serverless-app/#setup) has a quick setup guide. Takes like 5 minutes, we promise.)

## Use the Go template

The Framework will configure AWS for Go on your behalf.

There are a couple Go templates already included with the Framework as of v1.26 — aws-go for a basic service with two functions, and aws-go-dep for the basic service using the [dep](https://github.com/golang/dep) dependency management tool. Let's try the aws-go-dep template. **You will need [**dep](https://github.com/golang/dep)** installed.**

Make sure you’re in your [${GOPATH}/src](https://github.com/golang/go/wiki/GOPATH) directory, then run:
{% gist https://gist.github.com/richardgrantserverless/4cbdcc45e57986270b80716dc7456cff.js %}
Change into your new service directory and compile the function:
{% gist https://gist.github.com/richardgrantserverless/136afb0537b2230b6b1ee9bb797ef627.js %}
The default command in the included Makefile will gather your dependencies and build the proper binaries for your functions. You can deploy now:
{% gist https://gist.github.com/richardgrantserverless/a595bc8e5a70ebbef7f641c1a9e114a0.js %}
Finally, invoke your function:
{% gist https://gist.github.com/richardgrantserverless/a8f9047f23b88cf675c86d5d64728bcf.js %}
Nice!

### Building a Web API with Go + Lambda

The basic example is nice, but let’s try something a little more useful.

Lambda + API Gateway is awesome for quickly spinning up endpoints to retrieve or ingest data. So we’re going to build an example endpoint.

For our friends coming from interpreted, dynamically-typed languages (looking at you, Pythonistas & Javascript-lovers!), the Golang approach is a little different. You have to be a more intentional about the input & output of your functions. Don’t worry, we’ll take it slow. 😉

We’re going to make an HTTP endpoint that accepts a POST request at the path /echo, logs the POST body, and echoes the body back to the client.

First, let’s fix our serverless.yml to attach an HTTP event:
{% gist https://gist.github.com/richardgrantserverless/0aad9b558282a14958071db12a8a1eac.js %}
We’ll need to update our function in hello/main.go.

Remember, Golang is a compiled, statically-typed language, so we need to define the event object that's coming into our function. Fortunately, AWS has [provided a number of event types](https://github.com/aws/aws-lambda-go/tree/master/events) in a Github repo. 💥 We can just use those.

Update your hello/main.go to have the following code:
{% gist https://gist.github.com/richardgrantserverless/a929053b2803b47a3bf5844125303555.js %}
Our Handler() function now takes an APIGatewayProxyRequest object and returns a APIGatewayProxyResponse object. In our function code, we're printing the request body, then returning a response with the request body.

Recompile & deploy again:
{% gist https://gist.github.com/richardgrantserverless/7b878bccba908ba15f080e417fbcdf53.js %}
Notice that you now have an endpoint listed in your Service Information output.

Let’s use curl to hit your endpoint and get a response:
{% gist https://gist.github.com/richardgrantserverless/c558f7172ac3b8b5af4bd8dee791098a.js %}
Great! This should get you started on a web API. Feel free to check out the [other Lambda events in Golang](https://github.com/aws/aws-lambda-go/tree/master/events).

### Why use Go for your Lambdas?

Golang support for Lambda has been one of the most anticipated releases. The crowd at re:Invent was ecstatic when Werner announced Golang support was coming soon.

Why do people care about Golang so much? Simple: the combination of safety + speed.

As we saw above, Golang is a compiled, statically-typed language. This can help catch simple errors and maintain correctness as your application grows. This safety is really useful for production environments.

However, we’ve had Java and C# support in Lambda for years. These are both compiled, static languages as well. What’s the difference?

Java and C# both have notoriously slow cold-start time, in terms of multiple seconds. **With Go, the cold-start time is much lower.** In my haphazard testing, I was seeing cold-starts in the 200–400ms range, which is much closer to Python and Javascript.

Speed *and* safety. A pretty nice combo.

### A Gateway to all the runtimes

There’s one final note about the Golang implementation on Lambda that’s really interesting.

The main() function which is the entrypoint to our Golang binary *isn't* our Lambda handler function. It's a little RPC server that wraps our handler function:
{% gist https://gist.github.com/richardgrantserverless/b11f03ce8fa2a94a4d7a0cdcccfd31c1.js %}
[Under the covers](https://github.com/aws/aws-lambda-go/blob/master/lambda/entry.go#L37-L49), it looks like Lambda starts up your executable on a coldstart. The executable listens on a given port, receives input via JSON, and sends a response via JSON.

This opens up a lot of possibilities to bring other runtimes into Lambda. You just need to pull in an executable that implements the desired RPC interface.