初めてのGoでなれないところも多く悪戦苦闘していますが、共通処理を外に出してメンテナンス性やコード可読性をあげたいと思い、middlewareを実装してみました。
middleware用のコード
middleware.go
package middleware
import (
"github.com/aws/aws-lambda-go/events"
)
type Handler func(events.APIGatewayProxyRequest) (interface{}, error)
func Middleware(next Handler) Handler {
return Handler(func(request events.APIGatewayProxyRequest) (interface{}, error) {
return next(request)
})
}
handlerについての公式ドキュメントはこちら
https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/golang-handler.html
実際に組み込んだサンプルコード
main.go
package main
import (
"fmt"
"github.com/akihiro-moriwaki/lambda-middleware-go"
"github.com/aws/aws-lambda-go/events"
"github.com/aws/aws-lambda-go/lambda"
)
func handler(request events.APIGatewayProxyRequest, world string) (events.APIGatewayProxyResponse, error) {
return events.APIGatewayProxyResponse{
Body: fmt.Sprintf("Hello %s", world),
StatusCode: 200,
}, nil
}
type EventHandler func(events.APIGatewayProxyRequest, string) (events.APIGatewayProxyResponse, error)
func testEventHandler(h EventHandler) middleware.Handler {
return func(request events.APIGatewayProxyRequest) (interface{}, error) {
return h(request, "world")
}
}
func main() {
lambda.Start(
middleware.Middleware(
testEventHandler(
handler,
),
),
)
}
EventHandlerの引数に色々渡して行きます
type EventHandler func(events.APIGatewayProxyRequest, string) (events.APIGatewayProxyResponse, error)
Lambdaのstart、デフォルトだと
lambda.Start(handler)
こんな感じで、middlewareで挟みます。
lambda.Start(
middleware.Middleware(
testEventHandler(
handler,
),
),
)
「world」の文字列が渡され、レスポンスは「Hello world」となります
次は実用的な例で
DB接続をMiddlewareでやると
main.go
package main
import (
"database/sql"
"fmt"
"github.com/akihiro-moriwaki/lambda-middleware-go"
"github.com/aws/aws-lambda-go/events"
"github.com/aws/aws-lambda-go/lambda"
)
func handler(request events.APIGatewayProxyRequest, db *sql.DB) (events.APIGatewayProxyResponse, error) {
defer db.Close()
return events.APIGatewayProxyResponse{
Body: fmt.Sprintf("Hello world!"),
StatusCode: 200,
}, nil
}
type EventHandler func(events.APIGatewayProxyRequest, *sql.DB) (events.APIGatewayProxyResponse, error)
func dbEventHandler(h EventHandler) middleware.Handler {
return func(request events.APIGatewayProxyRequest) (interface{}, error) {
db, err := sql.Open("mysql", "user:password@tcp(host:port)/dbname")
if err != nil {
panic(err.Error())
}
return h(request, db)
}
}
func main() {
lambda.Start(
middleware.Middleware(
dbEventHandler(
handler,
),
),
)
}
簡単に実装しているのでもっと良い方法があれば教えてください
コード
コードはご自由にどうぞ、自己責任でお願いします。
変更したり消したりするかもしれませんので使う場合はコピーして使ってくださいね
https://github.com/akihiro-moriwaki/lambda-middleware-go
https://github.com/akihiro-moriwaki/lambda-middleware-sample