README
¶
AWS Lambda Go API Proxy (Echo v5 fork)
aws-lambda-go-api-proxy makes it easy to run Go APIs written with an HTTP framework on AWS Lambda,
behind either Amazon API Gateway or an Application Load Balancer.
Why this fork exists
awslabs/aws-lambda-go-api-proxy was archived
by its owner on May 21, 2025 and is now read-only. This fork exists because I needed two things the
upstream project can no longer provide: support for Echo v5, and fixes for how ALB target
group integration actually behaves.
It currently ships an Echo adapter only. I'm more than willing to add support for other frameworks — Gin, Fiber, Chi, GorillaMux, or anything else upstream carried — if there's interest from anyone else. Open an issue.
What's different from upstream
These are behavior changes. If you're coming from upstream, they're worth reading — three of the four fix failures that are close to invisible in production, because the Lambda runs fine, returns a well-formed response, and the client still gets a bare 502 with nothing logged to explain it.
- Echo v5 instead of v4. Handlers take
*echo.Context(a struct pointer), and path params use:namesyntax. - ALB
StatusDescriptionis emitted as"<code> <reason phrase>"(e.g.500 Internal Server Error). Upstream sends the bare reason phrase, which ALB treats as a malformed target response and replaces with its own 502 page — on every response, regardless of status code. - ALB response header names are lowercased. ALB rejects canonically-cased names (
Content-Type) the same way, with the same invisible 502. - ALB host resolution falls back to
MultiValueHeaders. With multi-value headers enabled on the target group, ALB populatesMultiValueHeadersand leavesHeadersnil. Upstream readsHeaders["host"]only, so every request resolved to an empty host. core.GatewayTimeoutALB()sets a well-formedStatusDescription. Upstream leaves it empty.
Getting started
# First, install the Lambda go libraries.
go get github.com/aws/aws-lambda-go/events
go get github.com/aws/aws-lambda-go/lambda
# Next, install this library.
go get github.com/mshindle/aws-lambda-go-api-proxy/...
Requires Go 1.26+ and github.com/labstack/echo/v5.
Echo behind an ALB
ALB is what this fork is primarily maintained for. Declare an echoadapter.EchoLambdaALB in the
global scope, initialize it in init with all your routes, and use ProxyWithContext to translate
requests and responses.
package main
import (
"context"
"github.com/aws/aws-lambda-go/events"
"github.com/aws/aws-lambda-go/lambda"
"github.com/labstack/echo/v5"
"github.com/mshindle/aws-lambda-go-api-proxy/echoadapter"
)
var albLambda *echoadapter.EchoLambdaALB
func init() {
e := echo.New()
e.GET("/ping", func(c *echo.Context) error {
return c.String(200, "pong")
})
albLambda = echoadapter.NewALB(e)
}
func handler(ctx context.Context, req events.ALBTargetGroupRequest) (events.ALBTargetGroupResponse, error) {
return albLambda.ProxyWithContext(ctx, req)
}
func main() {
lambda.Start(handler)
}
Enabling multi-value headers on the target group is supported and recommended — it's the only way to receive repeated request headers, and it's what the host-resolution fix above accounts for.
Echo behind API Gateway
Same shape, different constructor and event types. New handles API Gateway v1 (REST / proxy
integration):
var echoLambda *echoadapter.EchoLambda
func init() {
e := echo.New()
e.GET("/ping", func(c *echo.Context) error {
return c.String(200, "pong")
})
echoLambda = echoadapter.New(e)
}
func handler(ctx context.Context, req events.APIGatewayProxyRequest) (events.APIGatewayProxyResponse, error) {
return echoLambda.ProxyWithContext(ctx, req)
}
NewV2 handles API Gateway v2 (HTTP APIs):
var echoLambdaV2 *echoadapter.EchoLambdaV2
func init() {
e := echo.New()
e.GET("/ping", func(c *echo.Context) error {
return c.String(200, "pong")
})
echoLambdaV2 = echoadapter.NewV2(e)
}
func handler(ctx context.Context, req events.APIGatewayV2HTTPRequest) (events.APIGatewayV2HTTPResponse, error) {
return echoLambdaV2.ProxyWithContext(ctx, req)
}
Request context
The ALB or API Gateway request context, stage variables, and the Lambda runtime context are
populated into the request's context.Context automatically. Retrieve them with the core
accessors:
// ALB
albCtx, ok := core.GetTargetGroupRequestFromContextALB(ctx)
rtCtx, ok := core.GetRuntimeContextFromContextALB(ctx)
log.Println(albCtx.ELB.TargetGroupArn)
log.Println(rtCtx.InvokedFunctionArn)
// API Gateway v1
apiGwCtx, ok := core.GetAPIGatewayContextFromContext(ctx)
stageVars, ok := core.GetStageVarsFromContext(ctx)
log.Println(apiGwCtx.RequestID)
log.Println(apiGwCtx.Stage)
log.Println(stageVars["MyStageVar"])
// API Gateway v2
apiGwV2Ctx, ok := core.GetAPIGatewayV2ContextFromContext(ctx)
Supporting other frameworks
Alongside the adapters, this library declares a core package containing utility methods and
interfaces that translate Lambda proxy events into Go's standard http.Request and
http.ResponseWriter objects. Adding a framework means wiring those to that framework's
http.Handler.
Using the ALB adapter as the worked example: echoadapter/adapterALB.go
embeds the RequestAccessorALB struct defined in core/requestALB.go, which
provides ProxyEventToHTTPRequest() and EventToRequestWithContext().
EchoLambdaALB is initialized with an *echo.Echo, which implements http.Handler. Its Proxy
method receives an events.ALBTargetGroupRequest, converts it to an *http.Request, creates a
ProxyResponseWriterALB (defined in core/responseALB.go), and passes both
to the framework's ServeHTTP. ProxyResponseWriterALB.GetProxyResponse() then produces the
events.ALBTargetGroupResponse from whatever was written.
Support for any other framework relies on the same core methods, swapping *echo.Echo for that
framework's handler type. Contributions welcome.
License
This library is licensed under the Apache 2.0 License.
Directories
¶
| Path | Synopsis |
|---|---|
|
Package core provides utility methods that help convert proxy events into an http.Request and http.ResponseWriter
|
Package core provides utility methods that help convert proxy events into an http.Request and http.ResponseWriter |
|
Packge echoadapter add Echo support for the aws-severless-go-api library.
|
Packge echoadapter add Echo support for the aws-severless-go-api library. |