Skip to content

morelj/lambada

Repository files navigation

Lambada - Go net/http compatibility layer for AWS API Gateway Lambda functions

Lambada is a small Go package which provides a layer allowing to use Go's standard library net/http package to handle AWS API Gateway events in AWS Lambda functions.

It basically converts API Gateway events into http.Request, calls an http.Handler and converts the result written to the http.Response into an API Gateway response.

All libraries using http.Handler (e.g. multiplexers) should work using Lambada.

Lambada is compatible with both API Gateway V1 using the Lambda Proxy integration, and API Gateway V2 (HTTP API).

Installation

Install using go get:

go get github.com/morelj/lambada

Quick Start

The quickest way to get started with Lambada is simply to use the lambada.Serve function in place of lambda.Start:

import (
    "net/http"
    "github.com/morelj/lambada"
)

func main() {
    // Start the Lambda function handler with an http.Handler
    lambada.Serve(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
	       w.Write(([]byte)("<html><body><h1>Hello, World!</h1></body></html>"))
    }))
}

If you wish to control how do you start the Lambda handler, use lambada.NewHandler:

import (
    "net/http"
    "github.com/morelj/lambada"
    "github.com/aws/aws-lambda-go/lambda"
)

func main() {
    // Create a new handler
    h := lambada.NewHandler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
	       w.Write(([]byte)("<html><body><h1>Hello, World!</h1></body></html>"))
    })

    // Start the Lambda handler
    lambda.Start(h)
}

You can also customize how Lambada will behave by passing some options to lambada.NewHandler or lambada.ServeWithOptions. Available options are described below.

Logging

By default, Lambada does not log anything. It is however possible to log the incoming Lambda events and the Lambda response generated by Lambada.

Three options are available to control logging:

  • lambada.WithRequestLogger - Sets the request logger
  • lambada.WithResponseLogger - Sets the response logger
  • lambada.WithLogger - Sets both loggers

A Logger is a simple interface which is compatible with stdlib's log.Logger:

    lambada.ServeWithOptions(handler, lambada.WithLogger(log.Default()))

Lambada provides a NullLogger type which disables logging (which is used by default):

    lambada.ServeWithOptions(handler, lambada.WithLogger(lambada.NullLogger{}))

Responses with binary content

Returning responses with binary content can be a bit tedious using AWS Lambda and API Gateway, as the body must be base64 encoded.

By default, Lambada will always assume the response body is text only, but there are several options available.

Global option: Enabling binary by default

Using the lambada.WithDefaultBinary option, binary mode can be enabled for all requests:

    lambada.ServeWithOptions(handler, lambada.WithDefaultBinary(true))

Per request setting: Setting text or binary output for a specific request

Inside an HTTP handler, you can use the lambada.SetBinary and lambada.SetText to enable/disable binary for this specific request:

    h := lambada.NewHandler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        // Enable binary mode
        lambada.SetBinary(w)

        // Enable text mode
        lambada.SetText(w)
    })

Note that lambada.SetBinary and lambada.SetText have no effect when running the code on a non-Lambda environment.

Using Output Mode

The last but not least option is the output mode. Output mode controls how Lambada will process the request output body. There are three available output modes:

  • lambada.Manual - Nothing will be done. You'll have to call SetBinary or SetText to switch modes.
  • lambada.AutoContentType - This is the default. If your response does not include a Content-Type header, Lambada will sniff the response body (using http.DetectContentType) to set an appropriate Content-Type header. Nothing else will be done, so you'll still have to call SetBinary or SetText as needed.
  • lambada.Automatic - This mode will work as AutoContentType but will in addition enable or disable binary based on the Content-Type and Content-Encoding response headers. If Lambada cannot determine if the body is binary or not, the default value will be used.

The output mode can be set either globally using the lambada.WithOutputMode option or per request using lambada.SetOutputMode:

    h := lambada.NewHandler(
        http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
            // Set manual mode for this request specifically
            lambada.SetOutputMode(lambada.Manual)
        },
        // Use the Automatic mode globally
        lambada.WithOutputMode(lambada.Automatic),
    )

Note that lambada.SetOutputMode have no effect when running the code on a non-Lambda environment.

Accessing Lambada internals

Lambada aims to be an abstraction layer over AWS Lambda / API Gateway. However, it may sometimes be useful to access the original Lambda event.

Accessing the Lambda event

The lambada.GetRequest function returns the original Lambda event from a request's context:

    h := lambada.NewHandler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        // Get original request
        lambdaRequest := lambada.GetRequest(r.Context())
        if lambdaRequest != nil {
            // lambdaRequest contains the original event.
            // Note that the content will vary whether the event was an API Gateway v1 or v2 event.
        } else {
            // lambdaRequest is nil if the handler has not been called from a Lambda function
        }
    })

Accessing the response writer

It is also possible to unwrap to get the underlying lambda.ResponseWriter:

    h := lambada.NewHandler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        lambdaWriter, ok := w.(*lambada.ResponseWriter)
        if ok {
            // Do something with lambdaWriter
        } else {
            // The handler has not been called from a Lambda function
        }
    })

About

Go net/http compatibility layer for AWS API Gateway Lambda functions

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages