AWS SAM's HTTP interface sucks

Published: Saturday, Sep 12, 2020 Last modified: Sunday, Sep 20, 2020

A hello world http API implemented with AWS SAM looks like:

func handler(request events.APIGatewayProxyRequest) (events.APIGatewayProxyResponse, error) {
        return events.APIGatewayProxyResponse{
                StatusCode: 200,
                Headers: map[string]string{
                        "Content-Type": "text/plain",
                Body: "Hello World",
        }, nil

func main() {


Why didn’t they simply abstract this insane interface with the standard, portable and beautiful HTTP request response model?

func main() {
    addr := ":" + os.Getenv("PORT")
    http.HandleFunc("/", hello)
    log.Fatal(http.ListenAndServe(addr, nil))

func hello(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintln(w, "Hello World")


SAM’s events.APIGatewayProxyRequest is just awful to use. You have to test it within a Docker environment which is ~5s slow. If you use the standard interface, you can simply use the gin reloader and you have a very fast iterative workflow.

This is why I still use Apex Up to develop my Go HTTP functions. Allows me to use a standard sane interface and allows for a sane local workflow for fast, joyful development iterations.

What happens if Apex up is no more?

I recommend using Apex Up, but what happens if it falls away?

Apex Up author and savant @tjholowaychuk published his critical mapping and you can recreate Apex Up functionality labouriously with AWS SAM like so: