日本語の記事などが一つもなかったので備忘録も兼ねて
結論
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)