Go の Lambda 関数ハンドラーの定義
Lambda 関数ハンドラーは、イベントを処理する関数コード内のメソッドです。関数が呼び出されると、Lambda はハンドラーメソッドを実行します。関数は、ハンドラーが応答を返すか、終了するか、タイムアウトするまで実行されます。
Gomain()
関数の実装が必要となります。
例 Go Lambda 関数
package main import ( "context" "fmt" "github.com/aws/aws-lambda-go/lambda" ) type MyEvent struct { Name string `json:"name"` } func HandleRequest(ctx context.Context, event *MyEvent) (*string, error) { if event == nil { return nil, fmt.Errorf("received nil event") } message := fmt.Sprintf("Hello %s!", event.Name) return &message, nil } func main() { lambda.Start(HandleRequest) }
次に示すのはこの関数の入力例です。
{ "name": "Jane" }
次の点に注意してください。
-
package main: Go では、
func main()
を含むパッケージは常にmain
と名付けられることが必要です。 -
インポート: これを使用して、Lambda 関数に必要なライブラリを含めます。この場合、次のものが含まれます。
-
コンテキスト: Go の AWS Lambda context オブジェクト。
-
fmt: 関数の戻り値の書式に使用される Go フォーマット
オブジェクト。 -
github.com/aws/aws-lambda-go/lambda: 前に説明した Go 用の Lambda プログラミングモデルを実装します。
-
-
func HandleRequest(ctx context.Context, event *MyEvent) (*string, error): これは Lambda ハンドラーの署名です。Lambda 関数のエントリポイントであり、関数が呼び出されたときに実行されるロジックが含まれています。また、次に示すパラメータも含まれます。
-
ctx context.Context: Lambda 関数呼び出しへのランタイム情報を提供します。
ctx
は、Go の AWS Lambda context オブジェクト を介して利用できる情報を活用する宣言を行う変数です。 -
event *MyEvent: これは
MyEvent
をポイントするevent
という名前のパラメータです。Lambda 関数への入力を表します。 -
*string, error: ハンドラーは 2 つの値を返します。1 つ目は、Lambda 関数の結果を含む文字列へのポインタです。2 つ目はエラータイプで、エラーがない場合は
nil
となり、何か問題が発生した場合は標準的なエラー情報を含みます。 -
return &message, nil: 2 つの値を返します。1 つ目は文字列メッセージへのポインタです。これは、入力イベントの
Name
フィールドを使用して作成された挨拶文です。2 つ目の値はnil
であり、関数でエラーが発生しなかったことを示します。
-
-
func main(): Lambda 関数コードが実行されるエントリポイント。これは必須です。
func main(){}
コードの括弧内にlambda.Start(HandleRequest)
を追加すると、Lambda 関数が実行されます。Go 言語の規約に基づき、開き中括弧{
はmain
関数シグネチャの直後に置く必要があります。
命名
- provided.al2 および provided.al2023 ランタイム
-
.zip デプロイパッケージで
provided.al2
またはprovided.al2023
ランタイムを使用する Go 関数の場合、関数コードを含む実行ファイルの名前はbootstrap
である必要があります。.zip ファイルを使用して関数をデプロイする場合、bootstrap
ファイルは .zip ファイルのルートにある必要があります。コンテナイメージでprovided.al2
またはprovided.al2023
ランタイムを使用する Go 関数の場合、実行ファイルには任意の名前を使用できます。ハンドラーには任意の名前を使用できます。コード内でハンドラー値を参照するには、
_HANDLER
環境変数を使用できます。 - go1.x ランタイム
-
go1.x
ランタイムを使用する Go 関数の場合、実行ファイルとハンドラーは任意の名前を共有できます。例えば、ハンドラーの値をHandler
に設定すると、Lambda はHandler
実行可能ファイル内のmain()
関数を呼び出します。
Lambda コンソールの関数ハンドラー名を変更するには、ランタイム設定ペインで、[Edit] (編集) を選択します。
構造化されたタイプを使用した Lambda 関数ハンドラー
上記の例では、入力タイプは単純な文字列でした。ただし、構造化されたイベントを関数ハンドラーに渡すこともできます。
package main import ( "fmt" "github.com/aws/aws-lambda-go/lambda" ) type MyEvent struct { Name string `json:"What is your name?"` Age int `json:"How old are you?"` } type MyResponse struct { Message string `json:"Answer"` } func HandleLambdaEvent(event *MyEvent) (*MyResponse, error) { if event == nil { return nil, fmt.Errorf("received nil event") } return &MyResponse{Message: fmt.Sprintf("%s is %d years old!", event.Name, event.Age)}, nil } func main() { lambda.Start(HandleLambdaEvent) }
次に示すのはこの関数の入力例です。
{ "What is your name?": "Jim", "How old are you?": 33 }
レスポンスは次のようになります。
{ "Answer": "Jim is 33 years old!" }
エクスポートするには、イベント構造体のフィールド名が大文字である必要があります。AWS イベントソースでイベントを処理するための詳細は、「aws-lambda-go/events
有効なハンドラー署名
Go で Lambda 関数ハンドラーを構築するには複数の方法がありますが、次のルールに従う必要があります。
-
ハンドラーは関数である必要があります。
-
ハンドラーは 0 から 2 までの引数を取る場合があります。2 つの引数がある場合は、最初の引数が
context.Context
を実装する必要があります。 -
ハンドラーは 0 から 2 までの引数を返す場合があります。単一の戻り値がある場合は、この値が
error
を実装する必要があります。2 つの戻り値がある場合には、2 番目の値がerror
を実装している必要があります。
次のリストは、有効なハンドラー署名の一覧です。 TIn
と TOut
は、 encoding/json 標準ライブラリと互換性のあるタイプを表しています。詳細については、「func アンマーシャリング
-
func ()
-
func () error
-
func (TIn) error
-
func () (TOut, error)
-
func (context.Context) error
-
func (context.Context, TIn) error
-
func (context.Context) (TOut, error)
-
func (context.Context, TIn) (TOut, error)
グローバルな状態を使用する
Lambda 関数のハンドラーコードとは別のグローバルな変数を宣言して変更することができます。さらに、ハンドラーがロードされている場合に実行される init
関数をハンドラーが宣言することがあります。これは、AWS Lambda でも標準の Go プログラムと同じように作動します。Lambda 関数の単一のインスタンスが、同時に複数のイベントを処理することはありません。
例 グローバル変数を使用する Go 関数
注記
このコードは AWS SDK for Go V2 を使用します。詳細については、「Getting Started with the AWS SDK for Go V2
package main import ( "context" "github.com/aws/aws-lambda-go/lambda" "github.com/aws/aws-sdk-go-v2/config" "github.com/aws/aws-sdk-go-v2/service/s3" "github.com/aws/aws-sdk-go-v2/service/s3/types" "log" ) var invokeCount int var myObjects []types.Object func init() { // Load the SDK configuration cfg, err := config.LoadDefaultConfig(context.TODO()) if err != nil { log.Fatalf("Unable to load SDK config: %v", err) } // Initialize an S3 client svc := s3.NewFromConfig(cfg) // Define the bucket name as a variable so we can take its address bucketName := "DOC-EXAMPLE-BUCKET" input := &s3.ListObjectsV2Input{ Bucket: &bucketName, } // List objects in the bucket result, err := svc.ListObjectsV2(context.TODO(), input) if err != nil { log.Fatalf("Failed to list objects: %v", err) } myObjects = result.Contents } func LambdaHandler(ctx context.Context) (int, error) { invokeCount++ for i, obj := range myObjects { log.Printf("object[%d] size: %d key: %s", i, obj.Size, *obj.Key) } return invokeCount, nil } func main() { lambda.Start(LambdaHandler) }