AWSのAPIGateway+swagger



AWSのAPIGatewayを触ったがOpenAPI2.0の読み込みはやっていなかったので、
[AWSのドキュメント](https://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/create-api-using-swagger.html)を見ながら軽くswaggerについて確認しておいたメモ。

# AWSドキュメントのサンプル

一部AWS特有の項目があるようだが、以下がサンプルとして載っているJSON。
YAMLよりJSONの方が馴染みがあるのでこちらで見ていく。

```json
{
  "swagger": "2.0",
  "info": {
    "title": "Simple PetStore (OpenAPI)"
  },
  "schemes": [
    "https"
  ],
  "paths": {
    "/pets": {
      "get": {
        "responses": {
          "200": {
            "description": "200 response"
          }
        },
        "x-amazon-apigateway-integration": {
          "responses": {
            "default": {
              "statusCode": "200"
            }
          },
          "uri": "http://petstore-demo-endpoint.execute-api.com/petstore/pets",
          "passthroughBehavior": "when_no_match",
          "httpMethod": "GET",
          "type": "http"
        }
      }
    },
    "/pets/{petId}": {
      "get": {
        "parameters": [
          {
            "name": "petId",
            "in": "path",
            "required": true,
            "type": "string"
          }
        ],
        "responses": {
          "200": {
            "description": "200 response"
          }
        },
        "x-amazon-apigateway-integration": {
          "responses": {
            "default": {
              "statusCode": "200"
            }
          },
          "requestParameters": {
            "integration.request.path.id": "method.request.path.petId"
          },
          "uri": "http://petstore-demo-endpoint.execute-api.com/petstore/pets/{id}",
          "passthroughBehavior": "when_no_match",
          "httpMethod": "GET",
          "type": "http"
        }
      }
    }
  }
}
```
# 書き方

サンプルに加えて[定義](https://swagger.io/specification/v2/)を確認して、一部追加しながらメモしておく。
まずは全体的な情報

```json
{
  "swagger": "2.0",
  "info": {
    "title": "Simple PetStore (OpenAPI)",
    "version": "1.0.0",
    "description": "ペットストアに関するOpenAPIです"
  },
  "schemes": [
    "https","http"
  ],
  "paths": {
      ...
  }
}
```

 * swagger : バージョンは2.0がGateway対応。最新は3.0系？
 * info : title,versionが一般的には必須と思われる。他にdescription,contactやlisenceが記述可能
 * schemes: https,http以外にWebSockets系のws,wssも書ける
 * paths: 実際のAPIはこの下に定義

pathsの中身

```json
"/pets/{petId}": {
      "get": {
        "parameters": [
          {
            "name": "petId",
            "in": "path",
            "required": true,
            "type": "string"
          }
        ],
        "responses": {
          "200": {
            "description": "200 response",
            "schema": {
                "type": "object",
                "properties": {
                    "id": {
                        "type": "string"
                    },
                    "name":{
                        "type": "string"
                    }
                }
            }
          }
        },
        "x-amazon-apigateway-integration": {
          ...
        },
        "desctiption": "ペットIDを指定して情報を取得します"
      }
    }
```
大きくパラメータとレスポンスに分けられる。
x-amazon-apigateway-integrationは標準でないので一旦考えない。

 * メソッド: get,post,delete等
  * description: 説明 
  * parameters: **配列形式**で記述する。
   * name: パラメータ名
   * in: パラメータの場所。path,query, header, path, formData, bodyから選択
   * description: 説明
   * required: 必須かどうかtrue/false
   * type: パラメータの型。inがbody以外の場合にtring, number, integer, boolean, array, fileから選択。bodyの場合はschema属性で設定
  * responses: レスポンス情報。ステータス単位で記述していく
   * ステータス: 通常は200のみで良さそう。複数設定する場合も**配列ではない**
    * description: 説明
    * schema: bodyで返す際に記述
    * headers: レスポンスヘッダー
    * example: レスポンスの例

schemaを指定する際にはtype(object/array)とitemsやで構造を指定する。
 * schema 
  * type: object or array。jsonの形によって決める
   * properties: objectを選択した際に必要
    * name: {x,y}のx部分の値。 {"id",1}という場合ならid
     * type: string, number, integer, boolean, array, fileから選択
     * format: typeがstring,boolean以外の場合に設定。[ここ](https://swagger.io/specification/v2/)見る。
     * example: 値の例
   * items: typeでarrayを選択した場合はこの下にtype,propertiesをぶら下げる

## AWSの項目

x-amazon-apigateway-integrationはApiGatewayのLambdaプロキシ統合の設定になる。
[ここ](https://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/api-gateway-swagger-extensions-integration.html)が公式説明。

書き方が合っているかは微妙だが、以下のような形

```json
"x-amazon-apigateway-request-validator": "クエリ文字列パラメータおよびヘッダーの検証",
"x-amazon-apigateway-integration": {
    "responses": {
        "default": {
            "statusCode": "200"
        }
    },
    "requestTemplates" : {
        "application/json": "{\r\n  \"keys\": [{\"DeviceID\":\"$input.params('device')\"}]\r\n}"
    },
    "uri": "arn:aws:apigateway:ap-northeast-1:lambda:path/2015-03-31/functions/arn:aws:lambda:ap-northeast-1:000000000000:function:dynamoTest/invocations",
    "passthroughBehavior": "when_no_templates",
    "httpMethod": "POST",
    "contentHandling": "CONVERT_TO_TEXT",
    "type": "aws"
}
```

 * type: Lmbda統合の場合はaws_proxy、統合でない場合はaws
 * uri: 見る限りarn:aws:apigateway:ap-northeast-1:lambda:path/2015-03-31/functions/(lambdaARN)/invocations
 * passthroughBehavior: when_no_templates(推奨)かwhen_no_match
 * httpMethod: Lamnda関数の呼び出しの場合はPOST
 * connectionType: プライベート統合の場合のみVPC_LINKを指定し、connectionIdも設定する。
 * requestTemplates: テンプレートを利用する場合に指定。
 * requestParameters: ヘッダ、パス、クエリの設定。 [ここ](https://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/api-gateway-swagger-extensions-integration-requestParameters.html)
 * responses defaultのstatudCode:200をとりあえず指定しておけば通常はなんとかなる
 * contentHandling: Base64をテキストに変換する場合はCONVERT_TO_TEXT

その他[この辺り](https://blog.mori-soft.com/entry/2018/08/24/133304)に、少し前の情報だが色々。
CORSの設定等は通常はしておく方が良いはず。

なお、APIGatewayからswaggerの形式で出力する事が出来る。
APIを一度デプロイした後、ステージからswaggerの形式でエクスポートする。
拡張形式でもエクスポート出来るため、一度手で作成してから確認、雛型として使うのが早そう。