![見出し画像](https://assets.st-note.com/production/uploads/images/155101867/rectangle_large_type_2_4c764a0b385c8da90c19b16ae1c96b9c.png?width=1200)
API GatwayとLambdaを連携する
はじめに
API GatwayとLambda連携する方式を確認していたのですが、個々は想定通りに動くのに連携するとAPIからLambdaにデータが渡りません。調べてみると設定が必要らしい。ということでREST APIではどのようにLambdaにデータを渡すのかを整理しました。
Lambdaを作成する
最初に下記内容でLambdaを作成します。
関数名:TestLambda(任意)
ランタイム:Node.js 20.x
アーキテクチャ:x86_64
実行ロール:基本的なLambdaアクセス権限で新しいロールを作成
詳細設定:すべてOFF
コード:連携内容が分かるよう下記のようにeventの内容を文字列で返却
export const handler = async (event) => {
const eventStr ='headers:' + JSON.stringify(event, null, 2);
const response = {
statusCode: 200,
body: JSON.stringify(eventStr),
};
return response;
};
これでテストを実行してみます。
テストではテンプレートの「API Gateway HTTP API」を選択して、そのまま実行します。
想定通り、テンプレートで渡したヘッダー情報などが出力できます。
※見やすいよう改行などを整形しています。
Response
{
"statusCode": 200,
"body": ""headers:{
"version": "2.0",
"routeKey": "$default",
"rawPath": "/path/to/resource",
"rawQueryString": "parameter1=value1¶meter1=value2¶meter2=value",
"cookies": [
"cookie1",
"cookie2"
],
"headers": {
"Header1": "value1",
"Header2": "value1,value2"
},
"queryStringParameters": {
"parameter1": "value1,value2",
"parameter2": "value"
},
"requestContext": {
"accountId": "123456789012",
"apiId": "api-id",
以降省略
API Gatwayを作成する
次に下記内容でAPI Gatewayを作成して、Lambdaと連携させます。
API Gateway本体の設定
APIタイプ:REST API
APIの詳細:新しい API
API名:TestAPI(任意)
APIエンドポイントタイプ:リージョン
リソースの設定
プロキシのリソース:OFF
リソースパス:/
リソース名:{testId} ※パスパラメータも確認するため
CORS:OFF
メソッドの設定
メソッドタイプ:ANY ※テスト用のため
統合タイプ:Lambda関数
Lambdaプロキシ統合:OFF
Lambda関数:上で作成したLambdaを選択
統合のタイムアウト:29000(デフォルト)
メソッドリクエストの設定:設定無し(デフォルト)
URLクエリ文字列パラメータ:設定無し(デフォルト)
HTTPリクエストヘッダー:設定無し(デフォルト)
リクエスト本文:設定無し(デフォルト)
この内容でテストを実施すると下記になり、Lambdaに情報が渡っていないことが分かります。
{"statusCode":200,"body":"headers:{}"}
マッピングテンプレートを設定する
情報を渡すようにするためには、マッピングテンプレートを設定する必要があります。
上で設定したメソッドの統合リクエストを編集してマッピングテンプレートを下記のように追加します。
コンテンツタイプ:application/json
テンプレート本文:テンプレートを生成プルダウンからメソッドリクエストのパススルーを選択して設定されたものをそのまま使用
※下記は表示用に段組を少し整形
## See https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-mapping-template-reference.html
## This template will pass through all parameters including path, querystring, header, stage variables, and context through to the integration endpoint via the body/payload
#set($allParams = $input.params())
{
"body-json" : $input.json('$'),
"params" : {
#foreach($type in $allParams.keySet())
#set($params = $allParams.get($type))
"$type" : {
#foreach($paramName in $params.keySet())
"$paramName" : "$util.escapeJavaScript($params.get($paramName))"
#if($foreach.hasNext),#end
#end
}
#if($foreach.hasNext),#end
#end
},
"stage-variables" : {
#foreach($key in $stageVariables.keySet())
"$key" : "$util.escapeJavaScript($stageVariables.get($key))"
#if($foreach.hasNext),#end
#end
},
"context" : {
"account-id" : "$context.identity.accountId",
"api-id" : "$context.apiId",
"api-key" : "$context.identity.apiKey",
"authorizer-principal-id" : "$context.authorizer.principalId",
"caller" : "$context.identity.caller",
"cognito-authentication-provider" : "$context.identity.cognitoAuthenticationProvider",
"cognito-authentication-type" : "$context.identity.cognitoAuthenticationType",
"cognito-identity-id" : "$context.identity.cognitoIdentityId",
"cognito-identity-pool-id" : "$context.identity.cognitoIdentityPoolId",
"http-method" : "$context.httpMethod",
"stage" : "$context.stage",
"source-ip" : "$context.identity.sourceIp",
"user" : "$context.identity.user",
"user-agent" : "$context.identity.userAgent",
"user-arn" : "$context.identity.userArn",
"request-id" : "$context.requestId",
"resource-id" : "$context.resourceId",
"resource-path" : "$context.resourcePath"
}
}
改めてテストを実行すると下記の通りになり、データをLambdaに渡すことができました。
なおテストデータとしてパスパラメータ(testId)に123、クエリパラメータにparam=456、ヘッダー情報にheader1:789を設定しています。
{"statusCode":200,"body":""headers:{
"body-json": "あいうえお",
"params": {
"path": {
"testId": "123"
},
"querystring": {
"param": "456"
},
"header": {
"header1": "789"
}
},
以降省略
まとめ
API GatwayとLambda連携の設定に加え、マッピングテンプレートを設定することで、データまで連携できることが確認できました。
また参考のコードから、$input.params()ですべての情報が取得できることが見て取れるので、必要な情報だけをLambdaに渡すよう修正できれば良いことになります。