LoginSignup
2
0

API Gatewayを単一Lambda関数と統合する際のハンドラーのルーティング方法

Posted at

はじめに

API GatewayとLambdaの統合には様々な実装パターンがあるせいか、下記の状況下でのルーティングの方法の情報が無かったので投稿します。

前提

  • すべてのメソッドを単一のLambda関数とプロキシ統合する
  • プロキシリソース({proxy+})は使わない(HTTPルーティングはAPI Gatewayで行う)
  • aws-lambda-web-adapteraws-lambda-go-api-proxyなどは、使用しない

結論

Lambda関数が受け取るeventオブジェクトに含まれるresourcehttpMethodを使用する。
pathも使えそうですが、実際のパラメータが含まれる値のため、使用しない方が良いでしょう。

event
{
  "resource": "/todo/{id}",
  "path": "/todo/123",
  "httpMethod": "GET",
  ...
}

Goによるサンプル実装

main.go
package main

import (
	"context"
	"fmt"
	"net/http"

	"github.com/aws/aws-lambda-go/events"
	"github.com/aws/aws-lambda-go/lambda"
)

func Handler(ctx context.Context, event *events.APIGatewayProxyRequest) (*events.APIGatewayProxyResponse, error) {
	if event == nil {
		return nil, fmt.Errorf("event is null")
	}

	switch mr := event.HTTPMethod + " " + event.Resource; mr {
	case "GET /todo":
		return listTodoHandler(ctx, event)
	case "GET /todo/{id}":
		return getTodoHandler(ctx, event)
	case "POST /todo":
		return createTodoHandler(ctx, event)
	default:
		return nil, fmt.Errorf(`handler is not found: %s`, mr)
	}
}

リソース・メソッドで二段階の分岐や、文字列を関数化する等も良いかもしれません。
私自身は、逆に見通しが悪くなるように感じたので、単純な実装に留めました。

補足

メソッドリクエストの設定から、オペレーション名を設定することで、event内のrequestContextoperationNameが付与されます。こちらの値を使ってルーティングすることも可能です。
(当初は、こちらの方法を利用しようと思っていました。)

image.png

しかし、オペレーション名は任意項目であることに加え、複数のメソッドに同一の値を設定できてしまうことから、こちらの値を使用しない方が良いと判断しました。

(オペレーション名は、OpenAPIのoperationIdに対応する値なので、OpenAPI Spec 同様にユニーク制約があればよかったのですが)

2
0
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
2
0