Skip to content

Commit d5f36fd

Browse files
Fennykiyonlin
andauthored
🚀 Add Fiber (awslabs#69)
* Add Fiber * Update adapter.go * Update adapter.go * Update go.mod * Update go.sum * Update adapter.go * Update adapter.go * Update go.mod * Update adapter.go * Update adapter.go * Update adapter.go * ➕ add `ProxyWithContext` test case * ✅ fix package name typo and make test run * 📦 fiber v2 Co-authored-by: kiyon <[email protected]>
1 parent a0b7b0a commit d5f36fd

File tree

5 files changed

+417
-28
lines changed

5 files changed

+417
-28
lines changed

fiber/adapter.go

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
// Package fiberadapter adds Fiber support for the aws-severless-go-api library.
2+
// Uses the core package behind the scenes and exposes the New method to
3+
// get a new instance and Proxy method to send request to the Fiber app.
4+
package fiberadapter
5+
6+
import (
7+
"context"
8+
"io/ioutil"
9+
"net"
10+
"net/http"
11+
12+
"github.com/aws/aws-lambda-go/events"
13+
"github.com/awslabs/aws-lambda-go-api-proxy/core"
14+
"github.com/gofiber/fiber/v2"
15+
"github.com/gofiber/fiber/v2/utils"
16+
"github.com/valyala/fasthttp"
17+
)
18+
19+
// FiberLambda makes it easy to send API Gateway proxy events to a fiber.App.
20+
// The library transforms the proxy event into an HTTP request and then
21+
// creates a proxy response object from the *fiber.Ctx
22+
type FiberLambda struct {
23+
core.RequestAccessor
24+
app *fiber.App
25+
}
26+
27+
// New creates a new instance of the FiberLambda object.
28+
// Receives an initialized *fiber.App object - normally created with fiber.New().
29+
// It returns the initialized instance of the FiberLambda object.
30+
func New(app *fiber.App) *FiberLambda {
31+
return &FiberLambda{
32+
app: app,
33+
}
34+
}
35+
36+
// Proxy receives an API Gateway proxy event, transforms it into an http.Request
37+
// object, and sends it to the fiber.App for routing.
38+
// It returns a proxy response object generated from the http.ResponseWriter.
39+
func (f *FiberLambda) Proxy(req events.APIGatewayProxyRequest) (events.APIGatewayProxyResponse, error) {
40+
fiberRequest, err := f.ProxyEventToHTTPRequest(req)
41+
return f.proxyInternal(fiberRequest, err)
42+
}
43+
44+
// ProxyWithContext receives context and an API Gateway proxy event,
45+
// transforms them into an http.Request object, and sends it to the echo.Echo for routing.
46+
// It returns a proxy response object generated from the http.ResponseWriter.
47+
func (f *FiberLambda) ProxyWithContext(ctx context.Context, req events.APIGatewayProxyRequest) (events.APIGatewayProxyResponse, error) {
48+
fiberRequest, err := f.EventToRequestWithContext(ctx, req)
49+
return f.proxyInternal(fiberRequest, err)
50+
}
51+
52+
func (f *FiberLambda) proxyInternal(req *http.Request, err error) (events.APIGatewayProxyResponse, error) {
53+
54+
if err != nil {
55+
return core.GatewayTimeout(), core.NewLoggedError("Could not convert proxy event to request: %v", err)
56+
}
57+
58+
resp := core.NewProxyResponseWriter()
59+
f.adaptor(resp, req)
60+
61+
proxyResponse, err := resp.GetProxyResponse()
62+
if err != nil {
63+
return core.GatewayTimeout(), core.NewLoggedError("Error while generating proxy response: %v", err)
64+
}
65+
66+
return proxyResponse, nil
67+
}
68+
69+
func (f *FiberLambda) adaptor(w http.ResponseWriter, r *http.Request) {
70+
// New fasthttp request
71+
req := fasthttp.AcquireRequest()
72+
defer fasthttp.ReleaseRequest(req)
73+
74+
// Convert net/http -> fasthttp request
75+
body, err := ioutil.ReadAll(r.Body)
76+
if err != nil {
77+
http.Error(w, utils.StatusMessage(fiber.StatusInternalServerError), fiber.StatusInternalServerError)
78+
return
79+
}
80+
req.Header.SetContentLength(len(body))
81+
_, _ = req.BodyWriter().Write(body)
82+
83+
req.Header.SetMethod(r.Method)
84+
req.SetRequestURI(r.RequestURI)
85+
req.SetHost(r.Host)
86+
for key, val := range r.Header {
87+
for _, v := range val {
88+
req.Header.Add(key, v)
89+
}
90+
}
91+
92+
remoteAddr, err := net.ResolveTCPAddr("tcp", r.RemoteAddr)
93+
if err != nil {
94+
http.Error(w, utils.StatusMessage(fiber.StatusInternalServerError), fiber.StatusInternalServerError)
95+
return
96+
}
97+
98+
// New fasthttp Ctx
99+
var fctx fasthttp.RequestCtx
100+
fctx.Init(req, remoteAddr, nil)
101+
102+
// Pass RequestCtx to Fiber router
103+
f.app.Handler()(&fctx)
104+
105+
// Set response headers
106+
fctx.Response.Header.VisitAll(func(k, v []byte) {
107+
w.Header().Set(utils.UnsafeString(k), utils.UnsafeString(v))
108+
})
109+
110+
// Set response statuscode
111+
w.WriteHeader(fctx.Response.StatusCode())
112+
113+
// Set response body
114+
_, _ = w.Write(fctx.Response.Body())
115+
}

fiber/fiber_suite_test.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package fiberadapter_test
2+
3+
import (
4+
"testing"
5+
6+
. "github.com/onsi/ginkgo"
7+
. "github.com/onsi/gomega"
8+
)
9+
10+
func TestFiber(t *testing.T) {
11+
RegisterFailHandler(Fail)
12+
RunSpecs(t, "Fiber Suite")
13+
}

fiber/fiberlambda_test.go

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
package fiberadapter_test
2+
3+
import (
4+
"context"
5+
"log"
6+
7+
"github.com/aws/aws-lambda-go/events"
8+
fiberadaptor "github.com/awslabs/aws-lambda-go-api-proxy/fiber"
9+
"github.com/gofiber/fiber/v2"
10+
11+
. "github.com/onsi/ginkgo"
12+
. "github.com/onsi/gomega"
13+
)
14+
15+
var _ = Describe("FiberLambda tests", func() {
16+
Context("Simple ping request", func() {
17+
It("Proxies the event correctly", func() {
18+
log.Println("Starting test")
19+
app := fiber.New()
20+
app.Get("/ping", func(c *fiber.Ctx) error {
21+
log.Println("Handler!!")
22+
return c.SendString("pong")
23+
})
24+
25+
adapter := fiberadaptor.New(app)
26+
27+
req := events.APIGatewayProxyRequest{
28+
Path: "/ping",
29+
HTTPMethod: "GET",
30+
}
31+
32+
resp, err := adapter.ProxyWithContext(context.Background(), req)
33+
34+
Expect(err).To(BeNil())
35+
Expect(resp.StatusCode).To(Equal(200))
36+
37+
resp, err = adapter.Proxy(req)
38+
39+
Expect(err).To(BeNil())
40+
Expect(resp.StatusCode).To(Equal(200))
41+
})
42+
})
43+
})

go.mod

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,39 @@ module github.com/awslabs/aws-lambda-go-api-proxy
33
go 1.14
44

55
require (
6-
github.com/aws/aws-lambda-go v1.18.0
6+
github.com/ajg/form v1.5.1 // indirect
7+
github.com/andybalholm/brotli v1.0.1 // indirect
8+
github.com/aws/aws-lambda-go v1.19.1
9+
github.com/fasthttp-contrib/websocket v0.0.0-20160511215533-1f3b11f56072 // indirect
710
github.com/gin-gonic/gin v1.6.3
811
github.com/go-chi/chi v4.1.2+incompatible
12+
github.com/go-playground/validator/v10 v10.3.0 // indirect
13+
github.com/gofiber/fiber/v2 v2.1.0
14+
github.com/google/go-querystring v1.0.0 // indirect
915
github.com/gorilla/mux v1.7.4
16+
github.com/imkira/go-interpol v1.1.0 // indirect
17+
github.com/json-iterator/go v1.1.10 // indirect
18+
github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88 // indirect
19+
github.com/kataras/golog v0.0.18 // indirect
1020
github.com/kataras/iris/v12 v12.1.8
11-
github.com/labstack/echo/v4 v4.1.16
21+
github.com/klauspost/compress v1.11.1 // indirect
22+
github.com/labstack/echo/v4 v4.1.17
23+
github.com/mattn/go-colorable v0.1.8 // indirect
24+
github.com/microcosm-cc/bluemonday v1.0.3 // indirect
25+
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
26+
github.com/modern-go/reflect2 v1.0.1 // indirect
27+
github.com/moul/http2curl v1.0.0 // indirect
28+
github.com/onsi/ginkgo v1.14.0
29+
github.com/onsi/gomega v1.10.1
30+
github.com/sergi/go-diff v1.1.0 // indirect
31+
github.com/smartystreets/goconvey v1.6.4 // indirect
1232
github.com/urfave/negroni v1.0.0
33+
github.com/valyala/fasthttp v1.16.0
34+
github.com/xeipuuv/gojsonschema v1.2.0 // indirect
35+
github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0 // indirect
36+
github.com/yudai/gojsondiff v1.0.0 // indirect
37+
github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82 // indirect
38+
github.com/yudai/pp v2.0.1+incompatible // indirect
39+
golang.org/x/sys v0.0.0-20201016160150-f659759dc4ca // indirect
40+
google.golang.org/protobuf v1.25.0 // indirect
1341
)

0 commit comments

Comments
 (0)