LoginSignup
5
5

More than 3 years have passed since last update.

Lambdaでmiddleware実装 Go編

Posted at

初めての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

5
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
5