web-dev-qa-db-ja.com

AWS API Gatewayボディマッピングテンプレートの未加工ボディペイロード

何らかの理由で、eventから生のボディを取得するのに苦労しています。 $input.bodyのjsonとしてapplication/json content-type。 ドキュメントには、生のペイロードが含まれている必要があると記載されています。

ここに私の統合リクエストボディマッピングテンプレート:

{
  "body" : $input.json('$'),
  "rawBody": $input.body,
  "headers": {
    #foreach($header in $input.params().header.keySet())
    "$header": "$util.escapeJavaScript($input.params().header.get($header))" #if($foreach.hasNext),#end

    #end
  },
  "method": "$context.httpMethod",
  "params": {
    #foreach($param in $input.params().path.keySet())
    "$param": "$util.escapeJavaScript($input.params().path.get($param))" #if($foreach.hasNext),#end

    #end
  },
  "query": {
    #foreach($queryParam in $input.params().querystring.keySet())
    "$queryParam": "$util.escapeJavaScript($input.params().querystring.get($queryParam))" #if($foreach.hasNext),#end

    #end
  }  
}

ペイロードの例は次のとおりです。

{
  "event": {
    "body": {
      "hello": "meow"
    },
    "rawBody": {
      "hello": "meow"
    },
    "headers": {
      "Accept": "*/*",
      "Accept-Encoding": "gzip, deflate",
      "Accept-Language": "en-US",
      "Cache-Control": "no-cache",
      "CloudFront-Forwarded-Proto": "https",
      "CloudFront-Is-Desktop-Viewer": "true",
      "CloudFront-Is-Mobile-Viewer": "false",
      "CloudFront-Is-SmartTV-Viewer": "false",
      "CloudFront-Is-Tablet-Viewer": "false",
      "CloudFront-Viewer-Country": "US",
      "Content-Type": "application/json",
      "Host": "7nuy7lymef.execute-api.us-east-1.amazonaws.com",
      "Origin": "file://",
      "Postman-Token": "0ce7c6f4-3864-c9b4-f2db-739737b2ba49",
      "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) AppleWebKit/537.36 (KHTML, like Gecko) Postman/4.2.2 Chrome/47.0.2526.73 Electron/0.36.2 Safari/537.36",
      "Via": "1.1 1eea0bca59557555878da4d9775c509f.cloudfront.net (CloudFront)",
      "X-Amz-Cf-Id": "SDjaGcuJ5eVkOMMCn6M3vGaVicA1fuA7h0bUYE4ARlKupO60eeYNFA==",
      "X-Forwarded-For": "206.71.230.14, 205.251.250.135",
      "X-Forwarded-Port": "443",
      "X-Forwarded-Proto": "https",
      "x_example_header": "my awesome header"
    },
    "method": "POST",
    "params": {},
    "query": {
      "example_param": "myawesomeparam"
    }
  },
  "context": {
    "callbackWaitsForEmptyEventLoop": false,
    "logGroupName": "/aws/lambda/reggi-log-post",
    "logStreamName": "2016/06/08/[$LATEST]aad04e0e46614c288ac8ca43d0a95076",
    "functionName": "reggi-log-post",
    "memoryLimitInMB": "128",
    "functionVersion": "$LATEST",
    "invokeid": "6e4e1e13-2dc1-11e6-a1f7-4dad3a8eb122",
    "awsRequestId": "6e4e1e13-2dc1-11e6-a1f7-4dad3a8eb122",
    "invokedFunctionArn": "arn:aws:lambda:us-east-1:562508364089:function:reggi-log-post"
  }
}
  • このリクエストから生のボディにアクセスする方法はありますか?
  • すべてのタイプを受け入れるようにコンテンツタイプを変更する方法はありますか?
14
ThomasReggi

次のブログ投稿では、この問題を回避する方法について詳しく説明しています。 https://nicholasjackson.io/2016/12/13/using-graphql-with-aws-lambda/

具体的にはGraphQLのコンテキストで記述されていますが、どのコンテンツタイプでも機能します。要するに:

  • バイナリサポートセクションに移動します。選択したメディアタイプのバイナリサポートを有効にして保存します。
  • 「リソース」セクションのメソッドに戻り、統合リクエストを開きます。選択したコンテンツタイプの本文マッピングテンプレートを追加/編集し、以下を入力します。

    "rawBody": "$util.escapeJavaScript($util.base64Decode($input.body))"

  • APIを保存して再デプロイします。

バイナリサポートを追加すると、リクエストがbase64文字列としてエンコードされます。ボディマッピングテンプレートはそれをデコードします。

4
David L. Walsh

$input.bodyには未加工のペイロードが含まれます。 "rawBody": "$input.body"のように引用符で囲む必要があります。それ以外の場合、本文はjsonドキュメントの一部として解釈されます。

2