見出し画像

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&parameter1=value2&parameter2=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本体の設定

    1. APIタイプ:REST API

    2. APIの詳細:新しい API

    3. API名:TestAPI(任意)

    4. APIエンドポイントタイプ:リージョン

  • リソースの設定

    1. プロキシのリソース:OFF

    2. リソースパス:/

    3. リソース名:{testId} ※パスパラメータも確認するため

    4. CORS:OFF

  • メソッドの設定

    1. メソッドタイプ:ANY ※テスト用のため

    2. 統合タイプ:Lambda関数

    3. Lambdaプロキシ統合:OFF

    4. Lambda関数:上で作成したLambdaを選択

    5. 統合のタイムアウト:29000(デフォルト)

    6. メソッドリクエストの設定:設定無し(デフォルト)

    7. URLクエリ文字列パラメータ:設定無し(デフォルト)

    8. HTTPリクエストヘッダー:設定無し(デフォルト)

    9. リクエスト本文:設定無し(デフォルト)

この内容でテストを実施すると下記になり、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に渡すよう修正できれば良いことになります。

いいなと思ったら応援しよう!