LoginSignup
0
0

AWS Lambda(Go)で複数のイベントからリクエストを受け取る方法

Posted at

日本語の記事などが一つもなかったので備忘録も兼ねて

結論

Lambdaはジェネリクス型では対応できないため、reflectを使用する(一つのLambdaのみで対応する場合)

実装

// go version 1.19
package main

import (
	"context"
	"fmt"
	"reflect"

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

type TestEvent struct {
	events.SNSEvent
	events.APIGatewayProxyRequest
}

func mixHandler(context context.Context, event TestEvent) {
	switch {
	case !reflect.DeepEqual(event.SNSEvent, events.SNSEvent{}):
		// SNSの処理
	case !reflect.DeepEqual(event.APIGatewayProxyRequest, events.APIGatewayProxyRequest{}):
		// APIGateWayの処理
	default:
		fmt.Println("こちらは不明のリクエストを受け付けています。")
		logStr := fmt.Sprintf("%+v", event)
		fmt.Println(logStr)
		valueType := reflect.TypeOf(event)
		fmt.Println(valueType)
	}
}

func main() {
	lambda.Start(mixHandler)
}

解説

Lambdaにリクエストする予定のイベントの型を定義
(今回のケースだと、API GatewayとSNS)

type TestEvent struct {
	events.SNSEvent
	events.APIGatewayProxyRequest
}

reflect.DeepEqualで構造体比較をして、値が入っていれば処理に移る

switch {
	case !reflect.DeepEqual(event.SNSEvent, events.SNSEvent{}):
		// SNSの処理
	case !reflect.DeepEqual(event.APIGatewayProxyRequest, events.APIGatewayProxyRequest{}):
		// APIGateWayの処理
	default:
		fmt.Println("こちらは不明のリクエストを受け付けています。")
		logStr := fmt.Sprintf("%+v", event)
		fmt.Println(logStr)
		valueType := reflect.TypeOf(event)
		fmt.Println(valueType)
	}

以上です。

おまけ(ジェネリクス型を使った失敗)

package main

import (
	"fmt"
	"reflect"

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

type TestInterface interface {
	events.APIGatewayProxyRequest | events.SNSEvent
}

// ジェネリクス型
func mixHandler[T TestInterface](event T) {
	switch (interface{})(event).(type) {
	case events.SNSEvent:
		fmt.Println("こちらはSNSからのリクエストを受け付けています。")
		logStr := fmt.Sprintf("%+v", event)
		fmt.Println(logStr)
	case events.APIGatewayProxyRequest:
		fmt.Println("こちらはAPI Gatewayからのリクエストを受け付けています。")
		logStr := fmt.Sprintf("%+v", event)
		fmt.Println(logStr)
	default:
		fmt.Println("こちらは不明のリクエストを受け付けています。")
		logStr := fmt.Sprintf("%+v", event)
		fmt.Println(logStr)
		valueType := reflect.TypeOf(event)
		fmt.Println(valueType)
	}
}

func main() {
	lambda.Start(mixHandler)
}

こんな感じでジェネリクス型を定義して、受け取ったイベントをswitchで型判別して処理する方法を最初行おうとしていました。
ただ、 lambda.Start(mixHandler) で cannot use generic function mixHandler without instantiationエラーが発生して断念しました。
(ジェネリクス関数を使用する時はインスタンス化して使用しないといけないため、Lambdaでは使用できない)
※使用できる方法などあれば教えていただきたいです。

    // これは使用可能
	t := events.SNSEvent{}
	mixHandler(t)
0
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
0
0