John Todd
ErrthquakeHalo
← R&D
March 15, 2023

Developing AWS Lambdas and API Gateway v1

AWS Lambda connected to API Gateway is a cost-effective and scalable architecture for hosting APIs — but development requires specialized approaches since Lambda has no traditional host.

Background

Errthquake, a load and stress testing service, uses Lambda and API Gateway for its control API. The goal was an API that was reliable without requiring constant attention, because the test service itself is where most of the engineering effort goes.

API Gateway supports v1 and v2 request/response formats. v1 was chosen because v2 assumes your response will always be a JSON document — and file upload/download capabilities required v1's flexibility. Both the test service and Lambda functions are implemented in Go.

Lambda Handler Structure

A basic Go Lambda handler looks like this:

package main

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

func HandleRequest(ctx context.Context, event *events.APIGatewayProxyRequest) (events.APIGatewayProxyResponse, error) {
	contentResponse := events.APIGatewayProxyResponse{
		StatusCode: 200,
		Headers:    map[string]string{"Content-Type": "application/json"},
		Body:       "{\"message\":\"hello world\"}",
	}
	return contentResponse, nil
}

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

Local Development Architecture

A three-file structure separates concerns cleanly:

  • bootstrap.go — Initializes the Lambda runtime
  • lambda.go — Contains business logic (HandleRequest function)
  • exec.go — Local testing utility accepting JSON API Gateway v1 payloads

exec.go deserializes JSON into APIGatewayProxyRequest objects and serializes responses back to JSON — enabling full testing without any AWS infrastructure.

Deployment

Lambda supports x86 and ARM 64-bit architectures. Build for the target architecture:

GOARCH=arm64 GOOS=linux go build -o bootstrap -tags lambda.norpc bootstrap.go lambda.go
zip -FS my-api-lambda.zip bootstrap
aws lambda update-function-code \
  --function-name my-api-lambda \
  --zip-file fileb://$PWD/my-api-lambda.zip

Match the GOARCH value to the architecture you configured for the Lambda function in AWS (arm64 for Graviton, amd64 for x86).