SwaggerでAPIGateway + Lambdaの構成定義を書いたのでメモしておきます。
出来上がりのtemplate.yaml
AWSTemplateFormatVersion: '2010-09-09' Transform: 'AWS::Serverless-2016-10-31' Description: An AWS Serverless Specification template describing your function. Resources: getData: Type: 'AWS::Serverless::Function' Properties: CodeUri: getData/ Handler: get-data.lambda_handler Runtime: python3.6 Role: arn:aws:iam::****:role/your-lambda-execute-role Api: Type: 'AWS::Serverless::Api' Properties: StageName: Prod DefinitionBody: swagger: "2.0" info: version: "1.0" title: "lambda-web-interface" schemes: - "https" paths: /data: get: responses: {} x-amazon-apigateway-integration: uri: !Sub arn:aws:apigateway:ap-northeast-1:lambda:path/2015-03-31/functions/${getData.Arn}/invocations passthroughBehavior: "when_no_match" httpMethod: "POST" type: "aws_proxy" options: consumes: - application/json produces: - application/json x-amazon-apigateway-integration: type: mock requestTemplates: application/json: | { "statusCode" : 200 } responses: "default": statusCode: "200" responseParameters: method.response.header.Access-Control-Allow-Headers : "'Content-Type,X-Amz-Date,Authorization,X-Api-Key'" method.response.header.Access-Control-Allow-Methods : "'GET, POST, PUT, DELETE'" method.response.header.Access-Control-Allow-Origin : "'*'" responseTemplates: application/json: | {} responses: "200": headers: Access-Control-Allow-Headers: type: "string" Access-Control-Allow-Methods: type: "string" Access-Control-Allow-Origin: type: "string" getDataPermission: Type: "AWS::Lambda::Permission" Properties: Action: lambda:InvokeFunction FunctionName: !Ref getData Principal: apigateway.amazonaws.com
Lambda関数
getDataというLambda関数を定義します。関数の実装は、getData/
にget-data.py
という名前で作成してあります。
getData: Type: 'AWS::Serverless::Function' Properties: CodeUri: getData/ Handler: get-data.lambda_handler Runtime: python3.6 Role: arn:aws:iam::****:role/your-lambda-execute-role
API Gatewayの定義
Lambda呼び出しのインターフェース
REST APIでpath:data/
にGET時のAPI Gatewayの定義。同ファイル内に定義したLambda関数を呼び出すよう、uri: !Sub arn:aws:apigateway:ap-northeast-1:lambda:path/2015-03-31/functions/${getData.Arn}/invocations
と記述して参照してます。
Api: Type: 'AWS::Serverless::Api' Properties: StageName: Prod DefinitionBody: swagger: "2.0" info: version: "1.0" title: "lambda-web-interface" schemes: - "https" paths: /data: get: responses: {} x-amazon-apigateway-integration: uri: !Sub arn:aws:apigateway:ap-northeast-1:lambda:path/2015-03-31/functions/${getData.Arn}/invocations passthroughBehavior: "when_no_match" httpMethod: "POST" type: "aws_proxy"
x-amazon-apigateway-integration
はベンダー拡張の属性でAWS側のLambda関数のイベントソースとなる為の項目らしいです。httpMethod
はPOSTなるので注意。
参考: x-amazon-apigateway-integration オブジェクト - Amazon API Gateway
OPTIONメソッド プリフライトの定義
optionメソッドの定義にプリフライト時に許可するHeader、Origin、Methodを記述する。optionのtypeはラムダのイベントとはならないのでmock
と定義するみたいです。
options: consumes: - application/json produces: - application/json x-amazon-apigateway-integration: type: mock requestTemplates: application/json: | { "statusCode" : 200 } responses: "default": statusCode: "200" responseParameters: method.response.header.Access-Control-Allow-Headers : "'Content-Type,X-Amz-Date,Authorization,X-Api-Key'" method.response.header.Access-Control-Allow-Methods : "'GET, POST, PUT, DELETE'" method.response.header.Access-Control-Allow-Origin : "'*'" responseTemplates: application/json: | {} responses: "200": headers: Access-Control-Allow-Headers: type: "string" Access-Control-Allow-Methods: type: "string" Access-Control-Allow-Origin: type: "string"
ブラウザはOPTIONメソッドから返されたレスポンスを見て実際に送信可能であるか判断します。
Lambdaの実行権限
忘れずにLambdaの実行ロールを記述しよう。
getDataPermission: Type: "AWS::Lambda::Permission" Properties: Action: lambda:InvokeFunction FunctionName: !Ref getData Principal: apigateway.amazonaws.com
リンク