[AWS API Gateway / AWS Lambda] API Gatewayのためだけに存在するopenapi.yamlの項目について

# 概要

API Gatewayのステージ画面では、API仕様の定義をyamlファイルでエクスポートできるかと思います。

ここ↓の話です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/327407/5a86def4-f2f2-0c77-881d-31c1722f0cc3.png)

上記の通り、エクスポート方法には3種類ありますが、この記事では

- `OpenAPI 3 の形式でエクスポート`
- `OpenAPI 3 + API Gateway 拡張の形式でエクスポート`

だけを見ていきます。
そして、赤枠で囲んでいるこの2つの方式の差分を解明することを目指します。

# 願い

API Gatewayからエクスポートしたファイルを手元のPCで書き換えて、再インポートで望み通りの設定に変更できるようになりたい。
なんなら1から手元のPCでyamlを書いて、インポートだけで設定できるようになりたい。

というより、AWSコンソール画面でぽちぽちしたくない。
できるだけ最初から最後までGitで管理したい。

# AWS公式ドキュメント

ちなみに、AWSの公式ドキュメントにも`API Gateway 拡張`の話は掲載されていました。
本当に詳しいことが知りたい方はこちらもみてもいいかもしれません...。

[OpenAPI への API Gateway 拡張機能の使用](https://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/api-gateway-swagger-extensions.html)

最初見たとき私には理解できませんでした。
ただ、この記事を全部書いた後で見直してみたら、なんとなく何が書いてあるのかわかるようになりました。

この記事が皆さんの理解に貢献できれば幸いです...

# 差分

基本的には、`+ API Gateway 拡張`を選んだ場合に、`OpenAPI 3 の形式でエクスポート`では出力されなかった項目が追加で出力されるようです。

私が確認できている追加差分を一項目ずつ取り上げてみます。

## 1. x-amazon-apigateway-integration:

`paths:`内の`/パス名`の直下に`x-amazon-apigateway-integration:`なる項目が追加されていました。
この中身を詳しく見ていきたいと思います。

### 例）

```yaml
# API mockの例
      x-amazon-apigateway-integration:
        responses:
          default:
            statusCode: "200"
            responseParameters:
              method.response.header.Access-Control-Allow-Methods: "'DELETE,GET,HEAD,OPTIONS,PATCH,POST,PUT'"
              method.response.header.Access-Control-Allow-Headers: "'Content-Type,Authorization,X-Amz-Date,X-Api-Key,X-Amz-Security-Token'"
              method.response.header.Access-Control-Allow-Origin: "'*'"
        requestTemplates:
          application/json: "{\"statusCode\": 200}"
        passthroughBehavior: "when_no_match"
        type: "mock"
# ---

# Lambda関数を呼び出すAPIの例（Lambdaプロキシ統合ON）
      x-amazon-apigateway-integration:
        uri: "arn:aws:apigateway:us-east-1:lambda:path/2015-03-31/functions/arn:aws:lambda:us-east-1:xxxxxxxxxxxx:function:lambda_function_name/invocations"
        responses:
          default:
            statusCode: "200"
            responseParameters:
              method.response.header.Access-Control-Allow-Origin: "'*'"
        passthroughBehavior: "when_no_match"
        httpMethod: "POST"
        contentHandling: "CONVERT_TO_TEXT"
        type: "aws_proxy"

# ---

# Lambda関数を呼び出すAPIの例（Lambdaプロキシ統合OFF）
      x-amazon-apigateway-integration:
        uri: "arn:aws:apigateway:us-east-1:lambda:path/2015-03-31/functions/arn:aws:lambda:us-east-1:xxxxxxxxxxxx:function:lambda_function_name/invocations"
        responses:
          default:
            statusCode: "200"
            responseParameters:
              method.response.header.Access-Control-Allow-Origin: "'*'"
        requestParameters:
          integration.request.querystring.paramName: "method.request.querystring.paramName"
        passthroughBehavior: "when_no_templates"
        httpMethod: "POST"
        contentHandling: "CONVERT_TO_TEXT"
        type: "aws"
```

`mock`の例を比較対象とし、Lambda関数呼び出しのAPIを見ていきます。

### 1-1 uri:

見てある程度想像がつきますが、AWS上に構築したLambda関数を特定するための情報でしょう。
これは、以下の「**統合リクエスト**」画面で設定した内容が反映されています。

- 統合リクエスト画面の入り口
![2020-11-22_12h35_301.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/327407/af121424-7bd5-9684-70d6-6da84e40abe8.png)
- 統合リクエスト画面
![2020-11-22_12h39_11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/327407/6f0a5401-ee7a-3276-82d4-f2de84425645.png)

### 1-2 responses:

`responses`については、「**統合レスポンス**」画面で設定した項目が出力されていることがわかりました。

- 統合レスポンス画面の入り口
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/327407/abb890e3-3747-12ac-a950-57ca653c963b.png)
- 統合レスポンス画面
![2020-11-22_13h19_58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/327407/e15d1453-b2f9-488f-e55d-8e758575d5c2.png)

#### 1-2 補： 統合レスポンス画面が操作できない場合

ただし、「[1-1 uri:](https://qiita.com/siruku6/items/f98012cb5ca495cc7376#1-1-uri)」で取り上げた「**統合リクエスト**」画面において、`Lambda プロキシ統合の使用`にチェックを入れている場合、「**統合レスポンス**」画面への入り口が以下の状態になり、操作できません。

![2020-11-22_13h18_57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/327407/4ae0ffe5-a77c-571d-6669-ba20da1910d1.png)

この時は、API Gatewayサービスが自動でレスポンスを設定しているようです。

### 1-3 requestParameters: / passthroughBehavior:

`requestParameters` `passthroughBehavior` には、先ほども`uri`の話で出てきた「**統合リクエスト**」画面で設定した結果が反映されていました。

画面上でいうと、以下の赤枠のうち、

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/327407/f3f088ac-d7d7-eb24-19a2-2ebe44d4fe7b.png)

- **URLクエリ文字列パラメータ**  
`requestParameters`に反映される
- **マッピングテンプレート**  
`passthroughBehavior`に反映される

という関係性になっていました。

注意点としては、画像内で**黄色**マーカーを引いている、`Lambdaプロキシ統合の使用`にチェックが入っていると、赤枠の部分が消えてしまい、操作できなくなっていました。

`Lambdaプロキシ統合の使用`がONの場合、その辺を自動でうまくやってくれているのだと思われます。

### 1-4 httpMethod:

~~`httpMethod`は、皆様おわかりかと思いますので省略します！~~

[AWS 公式](https://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/api-gateway-swagger-extensions-integration.html)に書いてありましたが、どうやらAPI GatewayからLambdaを呼び出している場合は常に `POST` のようです！（勘違いしていました....）

### 1-5 contentHandling:

これは、わかりませんでした。

「**統合レスポンス**」画面内にある「コンテンツの処理」という項目が怪しいと思って操作してみたのですが、yaml内の`responses:`以下に`contentHandling:`という項目が作られるだけで、その1段上の`contentHandling:`はそのままでした。

ひとまず、常に `"CONVERT_TO_TEXT"` を入れておく方向で考えています。
情報求む！

### 1-6 type:

これは、yamlファイルの**例）**を見てもらえるとわかりやすいと思うのですが、

- 「**Lambdaプロキシ統合**」がON  
=> `"aws_proxy"`
- 「**Lambdaプロキシ統合**」がOFF  
=> `"aws"`

という値が記載されることがわかりました。

「**Lambdaプロキシ統合**」というのは、この記事で何度か出ていますが、「**統合リクエスト**」画面内で設定できる項目です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/327407/f8927b8e-13a8-79c4-8e3c-7e17691315b4.png)

やっていないのでわかりませんが、Lambda以外のサービスを呼び出すように設定すれば、`type`に他の値が入るのかもしれません。

## 2 x-amazon-apigateway-gateway-responses:

### 例）

```yaml
# サンプル
x-amazon-apigateway-gateway-responses:
  DEFAULT_5XX:
    responseParameters:
      gatewayresponse.header.Access-Control-Allow-Methods: "'GET,OPTIONS'"
      gatewayresponse.header.Access-Control-Allow-Headers: "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token'"
      gatewayresponse.header.Access-Control-Allow-Origin: "'*'"
  DEFAULT_4XX:
    responseParameters:
      gatewayresponse.header.Access-Control-Allow-Methods: "'GET,OPTIONS'"
      gatewayresponse.header.Access-Control-Allow-Headers: "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token'"
      gatewayresponse.header.Access-Control-Allow-Origin: "'*'"
```

`gateway-responses`という名前を頼りにAWSコンソール内を探索したところ、これらの値は以下の画面に設定されていました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/327407/8a89ed92-0d8d-6186-a600-564b942bf177.png)

4XX, 5XXともに、この「**ゲートウェイのレスポンス**」画面で確認できます。
ただ、個々の値を設定変更する方法は見つけられませんでした。

ひとまず、これらの値は常にこのままにするしか方法がなさそうです...。

ただ、`Access-Control-Allow-Methods`については、APIに含まれるHTTPメソッドの種類に応じて変わりそうなので、メソッドを増減・変更したいときは注意が必要そうです。

# まとめ

それぞれの項目は、画面内の以下の箇所で設定されていることがわかりました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/327407/718ece4e-92b1-ffc3-bf97-801d5c89a46f.png)

まだ私が見たことがない項目はまだまだあると思いますので、追加で判明した事項があれば追記していきたいと思っています。

しかし.....調べてみて思いましたが、yamlファイル側を修正してAPI Gatewayの設定をするのは、かなり難しいかもしれない(; ´ Д｀)