AWS API GatewayのBody Mapping Templateで使えるテンプレート
AWSのAPI Gatewayでは、リクエストをどう受けて、どう返すか、ということが設定できる。中間処理にLambdaを使う場合は、リクエストの情報をJSONオブジェクトに変換しておいて貰わないと、情報が来ない。
ということで、Body Mapping Template(後処理に渡すデータを生成するためのテンプレート)を使うわけだけど、以前には多分なかったテンプレートが追加されていたので試している。
Method Request Passthrough
2016/05/11時点では以下のような形をしている。cognitoの情報も追加できるようになっているので、おそらく今後も変化していくのだろうと想定。
## See http://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" } }
ざっくりと展開すると、以下の様な感じになる。だいたい自分でわかった範囲で説明もつけておく。雰囲気なので間違ってたらごめんなさい。
{ "body-json": [object], "params": { "path": [Empty Object], "querystring": [object], "header": [object], }, "stage-variables": [object], "context": [object] }
Key | Description | Type |
---|---|---|
body-json |
BodyをJSON.parseしたもの。 | object, array, ... |
params |
リクエスト時のパラメーター情報。 | object |
params.path |
(おそらく)基本的に空のオブジェクト。 | {} |
params.querystring |
URLクエリを処理したオブジェクト。配列クエリ、ネストされたクエリには対応されてなさそう。 | object |
params.header |
ヘッダ情報。 Host, Origin, User-Agent, などなど。 | object |
stage-variables |
API Gateway で設定したstageの情報。 | object |
context |
API Gatewayでリクエストを受けた時の状態。 | object |
context.http-method |
リクエストメソッド。GET, POST, など。 | string |
context.stage |
API Gateway でデプロイしているステージのラベル。 | string |
context.source-ip |
リクエストしてきたIPアドレス。 | string |
context.user-agent |
ユーザーエージェント文字列。 | string |
context.resource-path |
URLパスの文字列。基本的にAPI Gatewayのリソースに一致するはず。 | string |
バグ?
テンプレートにはバグっぽい挙動が含まれていて、POST時のリクエストBodyのJSONで文字列を含んでいるとエラーする。ダブルクオーテーションで囲ってしまっているため。ダブルクオーテーションを外してしまったほうが多分良いと思われる(思われるけど落とし穴があるかも)。
ref: https://forums.aws.amazon.com/thread.jspa?threadID=221749
-"body-json" : "$input.json('$')", +"body-json" : $input.json('$'),
ちなみにエラーすると、Lambdaは起動されない。Lambdaのログを監視していてもわからない問題になるので、検証は自己責任ということで。