API Gateway + AWS LambdaにPOSTした時のeventの中身


概要

HTTPでPOSTした際に、
AWS Lambdaのeventの中身はどういう形式か調査したので、共有する。

参考 : https://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/http-api-develop-integrations-lambda.html

curl -X POST -H "Content-Type: application/json" -d '{"Name":"Tanaka", "Age":"100"}' <api-url>

結論

eventの中身は、以下の設定によって変わる。

  1. lambda統合プロキシを使用している場合
  2. それ以外の場合

どこで設定するのかも詳しくみる。

A : 設定値によりeventが変わるパターン

1 : lambdaプロキシ統合を使用している場合

REST APIを使用している場合、
lambdaプロキシ統合を使用しているかどうか以下で判断できる。

このページの統合リクエストをクリックして

以下のチェックがついてるかどうか!

チェックがついてる場合、
eventは以下のjsonになる。

{
  "version": "2.0",
  "routeKey": "$default",
  "rawPath": "/my/path",
  "rawQueryString": "parameter1=value1&parameter1=value2&parameter2=value",
  "cookies": [
    "cookie1",
    "cookie2"
  ],
  "headers": {
    "Header1": "value1",
    "Header2": "value1,value2"
  },
  "queryStringParameters": {
    "parameter1": "value1,value2",
    "parameter2": "value"
  },
  "body": "Hello from Lambda",
  "pathParameters": {
    "parameter1": "value1"
  },
  "isBase64Encoded": false,
  "stageVariables": {
    "stageVariable1": "value1",
    "stageVariable2": "value2"
  }
  "requestContext": {
    "accountId": "123456789012",
    "apiId": "api-id",
    "authentication": {
      "clientCert": {
        "clientCertPem": "CERT_CONTENT",
        "subjectDN": "www.example.com",
        "issuerDN": "Example issuer",
        "serialNumber": "a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1",
        "validity": {
          "notBefore": "May 28 12:30:02 2019 GMT",
          "notAfter": "Aug  5 09:36:04 2021 GMT"
        }
      }
    },
    "authorizer": {
      "jwt": {
        "claims": {
          "claim1": "value1",
          "claim2": "value2"
        },
        "scopes": [
          "scope1",
          "scope2"
        ]
      }
    },
    "domainName": "id.execute-api.us-east-1.amazonaws.com",
    "domainPrefix": "id",
    "http": {
      "method": "POST",
      "path": "/my/path",
      "protocol": "HTTP/1.1",
      "sourceIp": "IP",
      "userAgent": "agent"
    },
    "requestId": "id",
    "routeKey": "$default",
    "stage": "$default",
    "time": "12/Mar/2020:19:03:58 +0000",
    "timeEpoch": 1583348638390
  }
}

つまり、bodyを取得したい場合は以下のコードでOK。

def lambda_handler(event, context):
    body = event["body"]
    print(body) # => {"Name":"Tanaka", "Age":"100"}

2 : それ以外の場合

マッピングテンプレートの設定値に準拠する。
lambdaプロキシ統合を下にスクロールすると、次の画面が現れる。

最も上の設定だと、そのまま通過する。
つまりbodyを以下のように取得できる。

def lambda_handler(event, context):
    print(event) # => {"Name":"Tanaka", "Age":"100"}

マッピングテンプレートを追加すると、eventsの情報を自分好みに変えることが可能。
詳しくはこちらの記事で。
https://dev.classmethod.jp/articles/api-gateway-mapping-template/

HTTP APIの場合は?

API GatewayにはREST APIだけでなく、HTTP APIもある。
HTTP APIの場合は、lambdaプロキシ統合に準拠してるっぽい(?)。
僕は設定値変えるところを見つけられなかった。