I like the newish AWSLabs Go API Proxy for this: https://github.com/awslabs/aws-lambda-go-api-proxy
It allows you to write a standard HTTP server using your tools of choice (plain old go, Gin, Gorilla, etc), then run that server on Lambda. It has several benefits:
- Removes almost all Lambda specific code/conventions from your codebase for more idiomatic go
- Easily covert existing golang HTTP server to lambda execution mode
- Support parallel execution modes. I use a ENV variable to switch between them in example below. I use straight HTTP for local dev, and Lambda for deployment.
Example app with 1 function
package main
import (
"fmt"
"io"
"log"
"net/http"
"os"
"github.com/aws/aws-lambda-go/lambda"
"github.com/awslabs/aws-lambda-go-api-proxy/httpadapter"
)
// map of our functions, which can be handled as HTTP or Lambda
var functions = map[string]http.HandlerFunc{
"ping": PingHandler,
}
func main() {
for name, handler := range functions {
path := fmt.Sprintf("/%s", name)
http.HandleFunc(path, handler)
}
httpPort := os.Getenv("HTTP_PORT")
if httpPort == "" {
log.Println("Starting Lambda Handler")
lambda.Start(httpadapter.New(http.DefaultServeMux).ProxyWithContext)
} else {
log.Printf("Starting HTTP server on port %s\n", httpPort)
formattedPort := fmt.Sprintf(":%s", httpPort)
log.Fatal(http.ListenAndServe(formattedPort, nil))
}
}
// Sample Func
func PingHandler(w http.ResponseWriter, r *http.Request) {
io.WriteString(w, "pong")
}
Running as HTTP is easy: go build -out main && HTTP_PORT=7575 ./main. This is super fast, making it easy to rebuilt and test.
You can still build and run in a docker container to test Lambda mapping before deploying using the steps others have mentioned.