How to build a Golang Lambda service with S3 integration

Golang Lambda Tutorial

Learn how to build a Golang Lambda service in a container, hook it up to a REST API end-point, and push and pull data from S3.

The Goal of this Golang Lambda Project

Here is the plan when I make a call like this:

>_curl  https://earthly-tools.com/text-mode?url=https://www.lipsum.com/

It will 1) hit the API gateway, 2) call my GoLang lambda function handler. My code will then 3) pull the site from the web and 4) clean it up to look like a text document and return it to the user. Last we will tackle 5) adding some caching into the mix.

But the end result is already up and running at https://earthly-tools.com/text-mode and will return something like this:

curl resultWhat is Lorem Ipsum?

   Lorem Ipsum is simply dummy text of the printing and typesetting
   industry. Lorem Ipsum has been the industry's standard dummy text ever
   since the 1500s, when an unknown printer took a galley of type and
   scrambled it to make a type specimen book. It has survived not only
   five centuries, but also the leap into electronic typesetting,
   remaining essentially unchanged. It was popularised in the 1960s with
   the release of Letraset sheets containing Lorem Ipsum passages, and
   more recently with desktop publishing software like Aldus PageMaker
   including versions of Lorem Ipsum.
   ...

And all in ~150 lines of Go code. So let’s do it.

The AWS Serverless REST API

When my Go Lambda is called via the lambda runtime, it will get a JSON event describing the request it received:

sample input{
  "queryStringParameters": {
    "url": "https://www.lipsum.com/"
  }
}

And, I’ll return an event describing the document I’d like produced.

sample output{
  statusCode: 200,
  headers: {
    "content-type": "text/plain; charset=utf-8"
  },
  body: "What is Lorem Ipsum?\n\n ..."
}

The whole thing has the feel of an old-fashion CGI Interface.

I represent the input JSON in Golang like this:

input typestype Event struct {
 QueryStringParameters QueryStringParameters `json:"queryStringParameters"`
}
type QueryStringParameters struct {
 Url string `json:"url"`
}

And output like so:

output typestype Response struct {
 StatusCode int               `json:"statusCode"`
 Body       string            `json:"body"`
 Headers    map[string]string `json:"headers"`
}

And, with those in place, I can write my lambda handler code.

The Golang Lambda Function