むだいありー

AWS SAMを使ってAPIを作るまで 後編

概要

前編からの続き。

AWSのSAM(Serverless Application Model)を使ってAPIを作成するまでの手順をまとめる。

後編ではRESTApiの設定を行う。

ディレクトリ構成

root/
┣ layers/
┃  ┗ common/
┃  ┃ ┗ common_layer.py
┃  ┗ ┗ requirements.txt
┣ src/
┃  ┗ get_function/
┃  ┃ ┗ __init.py__
┃  ┃ ┗ app.py
┃  ┗ ┗ requirements.txt
┃  ┗ get_rest_function/  <- このディレクトリを追加
┃  ┃ ┗ __init.py__
┃  ┃ ┗ app.py
┃  ┗ ┗ requirements.txt
┗ template.yaml

テンプレート追記

前回のtemplate.yamlに追記して、RESTApiの定義をする。


### 省略 ###

Globals:

  ### 省略 ###

  # RESTApiリソースへのグローバル定義
  Api:
    Cors:
      AllowOrigin: "'*'"
      AllowHeaders: "'X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token,Content-Type,Accept'"
      AllowMethods: "'GET,POST,PUT,DELETE,OPTIONS'"

Resources:

  ### 省略 ###

  # RESTAPI自体の定義
  GetFunctionRestApi:
    Type: AWS::Serverless::Api
    Properties:
      Name: GetFunctionRestApi
      StageName: Prod
      GatewayResponses:
        # Lambda関数のreturnまで行かなかった場合の、ApiGatewayのレスポンス設定
        DEFAULT_4XX:
          ResponseTemplates:
            "application/json": '{ "message": $context.error.messageString, "status": $context.status }'
          ResponseParameters:
            Headers:
              Access-Control-Allow-Origin: "'*'"
              Access-Control-Allow-Headers: "'X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token,Content-Type,Accept'"
              Access-Control-Allow-Methods: "'GET,POST,PUT,DELETE,OPTIONS'"
        DEFAULT_5XX:
          ResponseTemplates:
            "application/json": '{ "message": $context.error.messageString, "status": $context.status }'
          ResponseParameters:
            Headers:
              Access-Control-Allow-Origin: "'*'"
              Access-Control-Allow-Headers: "'X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token,Content-Type,Accept'"
              Access-Control-Allow-Methods: "'GET,POST,PUT,DELETE,OPTIONS'"
      Auth:
        Authorizers:
          GetFunctionRestApiAuth:
            # Cognito認証を有効化
            UserPoolArn: arn:aws:cognito-idp:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

  # RESTApi用のLambda関数の定義
  GetRestFunction:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: src/get_rest_function/
      Handler: app.lambda_handler
      Runtime: python3.8
      Layers:
        - !Ref MyApiLayer
      # For RDS Proxy
      Role: !GetAtt MyFunctionRoll.Arn
      VpcConfig:
        SecurityGroupIds:
          - sg-xxxxxx
        SubnetIds:
          - subnet-xxxxxxxx
          - subnet-xxxxxxxx
          - subnet-xxxxxxxx
      # Lambdaのトリガー設定(ApiGatewayのRESTApi)
      Events:
        GetRestEvent:
          Type: Api
          Properties:
            Path: /get-api-path
            Method: get
            RestApiId: !Ref GetFunctionRestApi
            Auth:
              Authorizer: GetFunctionRestApiAuth

Cognito認証とCORSの両立

Lmabda関数のレスポンスでAccess-Control-Allow-xxxheaderを返す必要がある。

{
    'statusCode': HTTPStatus.OK,
    'headers': {
        'Content-type': 'application/json',
        'Access-Control-Allow-Origin': '*',
        'Access-Control-Allow-Headers': 'X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token,Content-Type,Accept',
        'Access-Control-Allow-Methods': 'GET,POST,PUT,DELETE,OPTIONS'
    },
    'body': json.dumps(respose_param, ensure_ascii=False)
}

参考