LoginSignup
13
8

More than 3 years have passed since last update.

[AWS SAM] Swaggerを使用したAPI定義

Last updated at Posted at 2020-10-24
  1. [AWS SAM] 概要、Hello World
  2. [AWS SAM] Lambda関数からS3アクセス
  3. [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に変更する際のポイント

13
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13
8