API Gateway作成時にあるLambdaプロキシ統合というものが気になったので、少しまとめてみました。
ざっくりいうと、API Gatewayが受け取ったHTTPリクエスト全体を、evantパラメータとしてLambda関数に渡し、Lambda関数のレスポンスをそのままHTTPレスポンスとしてクライアントに返す統合方式です。
API Gatewayでは、レスポンスの形式を指定する方法として「マッピングテンプレート」がありますが、その設定も不要になっています。
今回はデフォルトのLambda関数で試してみようと思います。また、APIGatewayも2種類作成して比較しました。
import json
def lambda_handler(event, context):
# TODO implement
return {
'statusCode': 200,
'body': json.dumps('Hello from Lambda!')
}
Lambda統合プロキシの有無でそれぞれ以下のようにレスポンスが変化します。
Lambda統合プロキシありの場合
これは冒頭で示した公式ドキュメントにあるように、body部の値をレスポンス部分として返してくれるようになっているからです。今回は’Hello from Lambda!’の部分がそのまま返ってきてくれたわけですね。
{ "isBase64Encoded": true|false, "statusCode": httpStatusCode, "headers": { "headerName": "headerValue", ... }, "multiValueHeaders": { "headerName": ["headerValue", "headerValue2", ...], ... }, "body": "..." }
プロキシ統合を有効にすればあとはなんでもおっけ~というわけでもなく、Lambda入力時のお作法的なものも一応ありました。
{ "resource": "/my/path", "path": "/my/path", "httpMethod": "GET", "headers": { "header1": "value1", "header2": "value1,value2" }, "multiValueHeaders": { "header1": [ "value1" ], "header2": [ "value1", "value2" ] }, "queryStringParameters": { "parameter1": "value1,value2", "parameter2": "value" }, "multiValueQueryStringParameters": { "parameter1": [ "value1", "value2" ], "parameter2": [ "value" ] }, "requestContext": { "accountId": "123456789012", "apiId": "id", "authorizer": { "claims": null, "scopes": null }, "domainName": "id.execute-api.us-east-1.amazonaws.com", "domainPrefix": "id", "extendedRequestId": "request-id", "httpMethod": "GET", "identity": { "accessKey": null, "accountId": null, "caller": null, "cognitoAuthenticationProvider": null, "cognitoAuthenticationType": null, "cognitoIdentityId": null, "cognitoIdentityPoolId": null, "principalOrgId": null, "sourceIp": "IP", "user": null, "userAgent": "user-agent", "userArn": null, "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" } } }, "path": "/my/path", "protocol": "HTTP/1.1", "requestId": "id=", "requestTime": "04/Mar/2020:19:15:17 +0000", "requestTimeEpoch": 1583349317135, "resourceId": null, "resourcePath": "/my/path", "stage": "$default" }, "pathParameters": null, "stageVariables": null, "body": "Hello from Lambda!", "isBase64Encoded": false }
ここで実際に値の受け渡しをしているのは”queryStringParameters”ですね。これ含めて、eventオブジェクトとしてLambdaにこれらのパラメータを渡しているようです。ではこれを踏まえて実際に試してみようと思います。
以下のように’input_text’をeventオブジェクトとして受け取るように関数を変更します。
import json
def lambda_handler(event, context):
# TODO implement
return {
'statusCode': 200,
'body': json.dumps(event['queryStringParameters']['input_text'])
}
プロキシ統合有効時
プロキシ統合無効時
- エンドポイント指定→?input_text=hello
{
"errorMessage": "'queryStringParameters'",
"errorType": "KeyError",
"requestId": "55f41ab8-9120-4ca4-8d25-608fd343bb5a",
"stackTrace": [
" File \"/var/task/lambda_function.py\", line 7, in lambda_handler\n 'body': json.dumps(event['queryStringParameters']['input_text'])\n"
]
}
ここで言われているのは、’queryStringParameters’なんてキーないよと言われてしまっています。プロキシ統合を有効にすることでeventへのマッピングはすべてやってくれていたのですが、無効にしてしまうとやってくれないのでこのようなエラーが発生します。
マッピングテンプレートを使用する
プロキシ統合を使用せずにレスポンスを取得するにはマッピングテンプレートを使用するのも一つの手です。
プロキシ統合使用時はeventオブジェクトとして構造化して使用していましたが、マッピングテンプレートにレスポンスの形を明示的に示すことで構造を作ることができます。
今回は以下のように’input_text’を受け取れるようにしたいと思います。
再デプロイ後同様にリクエストを送ったところ、queryStringParametersの値にマッピングテンプレートを使用してアクセスできました。
LambdaやAPI Gatewayは普段あまり触らないですが、学びなおすいい機会になりました。
最近全然ブログ書けてなかったのでもう少し頻度上げていきたい…
Views: 2