AWS SAM's HTTP interface sucks

The API for AWS Serverless Application Model (AWS SAM) is non-standard and non-portable

Published: Saturday, Sep 12, 2020 Last modified: Sunday, Jun 9, 2024

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: