サーバーレス連載の3記事目です
TIGの伊藤真彦です。
GoでLambdaにデプロイするコードを書くにあたり、aws-lambda-goを利用できます。
その際のtips紹介記事です。
AWS LambdaにおけるGo Contextの取り扱い
package main |
aws-lambda-goライブラリのREADMEに記載の通り、importして利用可能になったaws-lambda-go/lambda
のStart
関数の引数に、アプリケーションコードを記載した関数を渡す形で、
実行するための土台としてのアレコレを抽象化して、アプリケーションコードに注力することが可能になっています。
lambda.Start(func)
に渡せる引数func
はinterface
型になっており、下記の複数種類の形式の関数を渡すことが可能になっています。
func () |
引数としてcontext.Context
型を受け取るシグネチャの関数を用いることで、後続処理でcontextを受け取ることが可能です。
LambdaContext型を利用する
contextというと後続のライブラリに受け渡すか、自前の実装によってタイムアウト等を管理するような用途が想定されます。
公式ドキュメントのサンプル実装はこちらです。
「context の呼び出し情報へのアクセス」の章に記載があるように、lambda.Start(func)
で実装した関数が受け取るcontext.Context
には、あらかじめいくつかの値が入っています。
これらの値をやり取りするために、aws-lambda-goにはlambdacontextパッケージが用意されています。
これにより、LambdaContext
構造体を用いることが可能です。
// LambdaContext is the set of metadata that is passed for every Invoke. |
この構造体は、フィールド名の通りAwsLambda
が実行された際の情報を持たせることが可能です。
context.ContextからLambdaContext構造体を復元する
// FromContext returns the LambdaContext value stored in ctx, if any. |
LambdaContext
構造体は、context.Context
を引数に取り、LambdaContext
構造体を返す関数FromContext
でデータを生成できます。FromContext
を用いたサンプルコードを書いてみました。
package main |
このような方法で、受け取ったcontextからライブラリがcontextに含めた情報を取得することが可能です。
実際の運用としては、ログ出力の際にprefixにAwsRequestID
を出力するように開発しておき、Amazon CloudWatch Logs
に送信されたログから、同一リクエストにおける一連のログ出力を抽出する際に役立てたりしています。
lambdaで開発したAPIの認証認可にAmazon Cognito
を利用している場合は、LambdaContext
構造体からCognitoIdentityID
、CognitoIdentityPoolID
を取得できるようになっています。
新しいcontext
にLambdaContext
構造体の情報を詰めるfunc NewContext(parent context.Context, lc *LambdaContext)
も用意されています。
このような公式から提供されているユーティリティを見落とさず使いこなしていきたいですね。
なお、Goの実装でLambdaを起動する際にcontext
に任意の値を保持して、リクエストのペイロードとして活用するような使い方はできません。
詳しくは過去記事GoでLambdaからLambdaを呼び出すときに気をつけたいポイント6選をご確認ください。
このようなGoでの実装経験、ハマりどころはServerless連載2: AWS Lambda×Goの開発Tipsなど、昨年の連載でも様々な記事が執筆されています。
この機会に合わせてお読みいただければ幸いです。
まとめ
- AWS lambdaをgoで実装する際にcontext.Contextを受け取るコードを実装できる
- contextにはリクエストID等の情報が含まれている
- contextの情報を扱うためのパッケージが用意されている