[AWS]APIGate+Lambdaで限定のAPIを作る

## 必要
- SAM(Serverless Achetecher Model)
- https://qiita.com/hayao_k/items/7827c3778a23c514e196
- AWSのアカウント

## UsagePlanは必須

API GatewayでAPIキーを使用してアクセス制御を行う場合は、Usage Plansが必要です。

- APIキーを作成する際、そのキーにどのようなルール（または制限）を適用するかをAPI Gatewayに指示する必要があります。このルールは「UsagePlan」と呼ばれます。
- UsagePlanとは、APIキーを何回使えるか（秘密のパスワードで何回ドアを開けられるか、というような）指示書のようなものです。
- リクエストがルールに従っていれば、API Gatewayはそのリクエストを通過させ、APIは想定された動作を行います。もしリクエストがルールに従っていない場合は、API Gatewayはそれをブロックし、通過させない。


```yaml
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: |
  backend
  Sample SAM Template for backend
Globals:
  Function:
    Timeout: 5
    MemorySize: 128
    Tracing: Active
  Api:
    TracingEnabled: true
Resources:
  ServerlessRestApi:
    Type: AWS::Serverless::Api
    Properties:
      StageName: Prod
  ApplicationResourceGroup:
    Type: AWS::ResourceGroups::Group
    Properties:
      Name: !Join
        - ''
        - - ApplicationInsights-SAM-
          - !Ref AWS::StackName
      ResourceQuery:
        Type: CLOUDFORMATION_STACK_1_0
  ApplicationInsightsMonitoring:
    Type: AWS::ApplicationInsights::Application
    Properties:
      ResourceGroupName: !Join
        - ''
        - - ApplicationInsights-SAM-
          - !Ref AWS::StackName
      AutoConfigurationEnabled: 'true'
    DependsOn: ApplicationResourceGroup
  # APIキーの設定
  MyApiKey:
    Type: AWS::ApiGateway::ApiKey
    Properties:
      Name: my-api-key
      Enabled: true
      GenerateDistinctId: true
      Description: My API Key
      StageKeys:
        - RestApiId: !Ref ServerlessRestApi
          StageName: Prod
  # APIキーと紐づいたプラン
  MyUsagePlan:
    Type: AWS::ApiGateway::UsagePlan
    Properties:
      UsagePlanName: my-usage-plan
      Description: My usage plan
      Quota:
        # 1000 requests per month
        Limit: 1000
        Period: MONTH
      Throttle:
        # 100 requests per second
        BurstLimit: 100
        # 50 requests per second
        RateLimit: 50
      ApiStages:
        - ApiId: !Ref ServerlessRestApi
          Stage: Prod
  # APIキーとプランを紐づける
  LinkUsagePlanApiKey:
    Type: "AWS::ApiGateway::UsagePlanKey"
    Properties:
      KeyId: 
       Ref: MyApiKey
      KeyType: API_KEY
      UsagePlanId: 
       Ref: MyUsagePlan

  LoginFn:
    Type: AWS::Serverless::Function
    Properties:
      Description: !Sub
        - Stack ${AWS::StackName} Function ${ResourceName}
        - ResourceName: LoginFn
      CodeUri: src/login
      Handler: main
      Runtime: go1.x
      MemorySize: 1000
      Timeout: 30
      Tracing: Active
      Events:
        LoginEndpoint:
          Type: Api
          Properties:
            Path: /login
            Method: POST
            RestApiId: !Ref ServerlessRestApi
            Auth:
              ApiKeyRequired: true
              ApiKey:
                Ref: MyApiKey

  LoginFnLogGroup:
    Type: AWS::Logs::LogGroup
    DeletionPolicy: Retain
    Properties:
      LogGroupName: !Sub /aws/lambda/${LoginFn}
  



# Outputs:
#   HelloWorldAPI:
#     Description: API Gateway endpoint URL for Prod environment for First Function
#     Value: !Sub https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/hello/
#   HelloWorldFunction:
#     Description: First Lambda Function ARN
#     Value: !GetAtt HelloWorldFunction.Arn
#   HelloWorldFunctionIamRole:
#     Description: Implicit IAM Role created for Hello World function
#     Value: !GetAtt HelloWorldFunctionRole.Arn
Metadata:
  AWS::Composer::Groups:
    Group:
      Label: Group
      Members:
        - ServerlessRestApi
```

## APIにリクエストを送る

apiキーなど必要な箇所を置き換えてください。

```
curl -X POST -H "Content-Type: application/json" -H "x-api-key: {api-key}" -d '{"username": "user1", "password": "pass1"}' https://{your-api-endpoint}.execute-api.{region}.amazonaws.com/Prod/login


```