- [AWS SAM] 概要、Hello World
- [AWS SAM] Lambda関数からS3アクセス
- [AWS SAM] Swaggerを使用したAPI定義 (※本記事)
Swaggerについて
RESTful APIを構築するためのオープンソースのフレームワーク
記述形式はJSONまたはYAML
バージョン2と3があり記述方法が異なるため注意
Swaggerで定義したAPIをSAMテンプレートから参照して使用する
【SAM】API定義とSwaggerファイル連携
必須項目のみでのAPI定義
以下のようにAPI Gatewayを表すTypeと、デプロイするステージ名が必須項目
Resources:
RestApi:
Type: AWS::Serverless::Api # API Gateway
Properties:
StageName: Dev # デプロイするステージ名
このAPIをLambdaのトリガとする場合、Lambdaの定義は以下のようになる
GetDataFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: get-data/
Handler: function.lambda_handler
Runtime: python3.8
Events:
getData:
Type: Api
Properties:
Path: /api/devices/{SerialNumber}
Method: get
RestApiId: !Ref RestApi # RestApiの定義を参照
SAMからSwaggerの参照
以下のようにDefinitionBodyでSwaggerファイルのパスを指定する
RestApi:
Type: AWS::Serverless::Api
Properties:
StageName: Dev
DefinitionBody:
Fn::Transform:
Name: AWS::Include
Parameters:
Location: swagger.yaml # swaggerファイルのパス指定
【Swagger】API定義
パス/api/devices/{SerialNumber}
のGET、POSTメソッドを以下で定義
openapi: 3.0.1
info:
description: 'REST API 定義'
version: '1.0.0'
title:
Fn::Sub: ${AWS::StackName}_restApi # API Gatewayに生成されるAPI名
paths:
/api/devices/{SerialNumber}: # APIのパス
get: # GETメソッド
summary: 'デバイス情報取得API'
parameters:
- name: SerialNumber
in: path # パラメータの場所:パスパラメータ
description: 'デバイスシリアル番号'
required: true # 必須パラメータ
schema: # パラメータ構造
type: string
responses:
200:
description: '成功時のレスポンス'
content:
application/json:
schema:
$ref: '#/components/schemas/device'
x-amazon-apigateway-integration:
uri: # APIからキックするLambda関数のARN
Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${GetDataFunction.Arn}/invocations
passthroughBehavior: when_no_templates
httpMethod: POST # Lambda関数を呼び出す場合はPOST
type: aws_proxy # Lambda関数を呼び出す場合はaws_proxy
post: # POSTメソッド
summary: 'デバイス情報設定API'
parameters:
- name: SerialNumber
in: path
description: 'デバイスシリアル番号'
required: true
schema:
type: string
requestBody: # bodyでデータを受け取る
content:
application/json:
schema:
$ref: '#/components/schemas/device'
responses:
200:
description: '成功時のレスポンス'
x-amazon-apigateway-integration:
uri:
Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${SetDataFunction.Arn}/invocations
passthroughBehavior: when_no_templates
httpMethod: POST
type: aws_proxy
components:
schemas:
device: # {'SerialNumber': 'abc-001', 'type': 1, 'status': 'working', 'power': 50}を定義
type: object
properties:
SerialNumber:
type: string
type:
type: integer
status:
type: string
power:
type: integer
deviceList: # deviceのListを定義
type: object
properties:
items:
type: array
items:
$ref: '#/components/schemas/device'
x-amazon-apigateway-integration:
はAPI Gateway, Lambda連携で必要な設定、詳細は公式ドキュメント参照
【SAM】その他API設定
API Gatewayへのアクセスのコントロール設定
今回はIAMアクセス許可を設定したいため以下のようにAuthを追加
RestApi:
Type: AWS::Serverless::Api
Properties:
StageName: Dev
Auth:
DefaultAuthorizer: AWS_IAM # IAMアクセス許可
DefinitionBody:
Fn::Transform:
Name: AWS::Include
Parameters:
Location: swagger.yaml
その他のアクセスコントロールについては公式ドキュメントを参照
CORS対応
RestApi:
Type: AWS::Serverless::Api
Properties:
StageName: Dev
Auth:
AddDefaultAuthorizerToCorsPreflight: false # OPTIONSメソッドにIAM認証をつけないための設定
DefaultAuthorizer: AWS_IAM
DefinitionBody:
Fn::Transform:
Name: AWS::Include
Parameters:
Location: swagger.yaml
Cors: # CORS追加
# 以下マネージメントコンソールでCORS設定した場合の内容に合わせて設定
AllowOrigin: "'*'"
AllowHeaders: "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token'"
AllowMethods: "'GET, OPTIONS'"
AllowCredentials: "'true'"
Lambdaプロキシ統合を使用している場合は、
上記と合わせてLambda側でレスポンスヘッダを設定する必要がある
return {
'statusCode': 200,
'headers': {
'Access-Control-Allow-Headers': 'Content-Type',
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'OPTIONS,POST,GET'
}
}
Stageにデプロイされる問題
勝手にStage
ステージにデプロイされてしまうため以下のようにOpenApiVersionを追加する
RestApi:
Type: AWS::Serverless::Api
Properties:
StageName: dev
Auth:
AddDefaultAuthorizerToCorsPreflight: false
DefaultAuthorizer: AWS_IAM
DefinitionBody:
Fn::Transform:
Name: AWS::Include
Parameters:
Location: swagger.yaml
Cors:
AllowOrigin: "'*'"
AllowHeaders: "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token'"
AllowMethods: "'GET, OPTIONS'"
AllowCredentials: "'true'"
OpenApiVersion: 3.0.2 # 追加
参考記事
【初心者向け】SwaggerとAWS SAMを使ってWebAPIを簡単に作ってみた
API仕様書書くならswagger v2.0からv3.0に変更する際のポイント