diff --git a/chi/adapterv2.go b/chi/adapterv2.go new file mode 100644 index 0000000..1220792 --- /dev/null +++ b/chi/adapterv2.go @@ -0,0 +1,59 @@ +package chiadapter + +import ( + "context" + "net/http" + + "github.com/aws/aws-lambda-go/events" + "github.com/awslabs/aws-lambda-go-api-proxy/core" + "github.com/go-chi/chi/v5" +) + +// ChiLambdaV2 makes it easy to send API Gateway proxy V2 events to a Chi +// Mux. The library transforms the proxy event into an HTTP request and then +// creates a proxy response object from the http.ResponseWriter +type ChiLambdaV2 struct { + core.RequestAccessorV2 + + chiMux *chi.Mux +} + +// New creates a new instance of the ChiLambdaV2 object. +// Receives an initialized *chi.Mux object - normally created with chi.NewRouter(). +// It returns the initialized instance of the ChiLambdaV2 object. +func NewV2(chi *chi.Mux) *ChiLambdaV2 { + return &ChiLambdaV2{chiMux: chi} +} + +// Proxy receives an API Gateway proxy V2 event, transforms it into an http.Request +// object, and sends it to the chi.Mux for routing. +// It returns a proxy response object generated from the http.ResponseWriter. +func (g *ChiLambdaV2) Proxy(req events.APIGatewayV2HTTPRequest) (events.APIGatewayV2HTTPResponse, error) { + chiRequest, err := g.ProxyEventToHTTPRequest(req) + return g.proxyInternal(chiRequest, err) +} + +// ProxyWithContext receives context and an API Gateway proxy V2 event, +// transforms them into an http.Request object, and sends it to the chi.Mux for routing. +// It returns a proxy response object generated from the http.ResponseWriter. +func (g *ChiLambdaV2) ProxyWithContextV2(ctx context.Context, req events.APIGatewayV2HTTPRequest) (events.APIGatewayV2HTTPResponse, error) { + chiRequest, err := g.EventToRequestWithContext(ctx, req) + return g.proxyInternal(chiRequest, err) +} + +func (g *ChiLambdaV2) proxyInternal(chiRequest *http.Request, err error) (events.APIGatewayV2HTTPResponse, error) { + + if err != nil { + return core.GatewayTimeoutV2(), core.NewLoggedError("Could not convert proxy event to request: %v", err) + } + + respWriter := core.NewProxyResponseWriterV2() + g.chiMux.ServeHTTP(http.ResponseWriter(respWriter), chiRequest) + + proxyResponse, err := respWriter.GetProxyResponse() + if err != nil { + return core.GatewayTimeoutV2(), core.NewLoggedError("Error while generating proxy response: %v", err) + } + + return proxyResponse, nil +} diff --git a/chi/chilambda_test.go b/chi/chilambda_test.go index 0589d52..ce6cf17 100644 --- a/chi/chilambda_test.go +++ b/chi/chilambda_test.go @@ -41,3 +41,36 @@ var _ = Describe("ChiLambda tests", func() { }) }) }) + +var _ = Describe("ChiLambdaV2 tests", func() { + Context("Simple ping request", func() { + It("Proxies the event correctly", func() { + log.Println("Starting test") + + r := chi.NewRouter() + r.Get("/ping", func(w http.ResponseWriter, r *http.Request) { + w.Write([]byte("pong")) + }) + + adapter := chiadapter.NewV2(r) + + req := events.APIGatewayV2HTTPRequest{ + RequestContext: events.APIGatewayV2HTTPRequestContext{ + HTTP: events.APIGatewayV2HTTPRequestContextHTTPDescription{ + Method: "GET", + Path: "/ping", + }, + }, + } + + resp, err := adapter.ProxyWithContextV2(context.Background(), req) + + Expect(err).To(BeNil()) + Expect(resp.StatusCode).To(Equal(200)) + + resp, err = adapter.Proxy(req) + Expect(err).To(BeNil()) + Expect(resp.StatusCode).To(Equal(200)) + }) + }) +})