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).
Install using go get
:
go get github.com/morelj/lambada
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.
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 loggerlambada.WithResponseLogger
- Sets the response loggerlambada.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{}))
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.
Using the lambada.WithDefaultBinary
option, binary mode can be enabled for all requests:
lambada.ServeWithOptions(handler, lambada.WithDefaultBinary(true))
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.
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 callSetBinary
orSetText
to switch modes.lambada.AutoContentType
- This is the default. If your response does not include aContent-Type
header, Lambada will sniff the response body (usinghttp.DetectContentType
) to set an appropriateContent-Type
header. Nothing else will be done, so you'll still have to callSetBinary
orSetText
as needed.lambada.Automatic
- This mode will work asAutoContentType
but will in addition enable or disable binary based on theContent-Type
andContent-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.
Lambada aims to be an abstraction layer over AWS Lambda / API Gateway. However, it may sometimes be useful to access the original 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
}
})
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
}
})