LoginSignup
22
17

More than 5 years have passed since last update.

Tips: API Gatewayのエクスポート/インポートでハマったところ

Last updated at Posted at 2015-12-24

AWSコンソールからAPI Gatewayの設定をいじってたんですが、何を変更したかわからなくなったり、変更した差分が欲しかったりしたのでswagger用のファイルで管理することにしました。
ツールもあるのですんなり出来るかと思いましたが、いくつかハマった部分があるので残しときます。

Export

AWSコンソールから行えます。
エクスポートしたいAPIのStageを選択し、右にあるExportタブからYAML / JSONがダウンロードできます。

API_Gateway.png

なおエクスポートされるのはそのStageで使用しているリソースやモデルのみで、例えばErrorやEmptyといったデフォルトで用意されているAPI Gatewayのモデルも使ってなければエクスポートしたファイルには含まれません。

Export as Swagger

swaggerの定義ファイルのみ。
これをインポートしてもリソース定義のみでAPI Gateway独自の認証や呼び出すLambda Functionなどの設定はされません。

Export as Swagger + API Gateway Extentions

上記に加えAPI Gateway用の設定もエクスポートされます。
各リソースの設定などを含んでますので後述するaws-apigateway-importerでインポートするならこれでエクスポートしたファイルを使うのが良さそうです。

Export as Swagger + Postman Extentions

Postman用の設定が追加?
見たところPostmanでテストするのに必要なリクエストヘッダが追加されてるようです。
Chrome Extension版はデバッグ時などによく使いますね。

Import

こちらのツールを使います。
https://github.com/awslabs/aws-apigateway-importer

使い方はクラスメソッドさんの記事がわかりやすいです。
http://dev.classmethod.jp/cloud/api-gateway-swagger-importer/

なお以降の記事は以下の実行環境で試してます。

  • aws-apigateway-importer
    commit 626a9c98cf05dbd040f6a87e978b9edf71d7209d
  • java
    homebrewでインストールした java version "1.8.0_66"

ハマった部分

ビルド時にjavac: 1.8は無効なターゲット・リリースですのエラー

  • エラーメッセージ
[ERROR] Failure executing javac, but could not parse the error:
javac: 1.8は無効なターゲット・リリースです
使用方法: javac <options> <source files>
使用可能なオプションのリストについては、-helpを使用します
  • 原因
    java 1.7だとダメみたいです。
    homebrewで1.8に更新したら無事ビルド成功しました。

Auth type is requiredのエラー

  • エラーメッセージ
2015-12-24 15:58:26,839 ERROR - Error creating API, rolling back
com.amazonaws.services.apigateway.model.BadRequestException: AWS_IAM Auth type is required for AWS integrations with identity forwarding specified (Service: null; Status Code: 400; Error Code: null; Request ID: xxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx)
  • 原因 githubのREADME.mdに記載がありますが、各リソースにx-amazon-apigateway-authの定義がないことが原因です。 x-amazon-apigateway-integrationと同じ階層に追加してあげればOK。
swagger.yaml
      x-amazon-apigateway-auth:
        type: "aws_iam"
      x-amazon-apigateway-integration:

Invalid mapping expressionのエラー

  • エラーメッセージ
2015-12-24 15:49:42,674 ERROR - Error creating API, rolling back
com.amazonaws.services.apigateway.model.BadRequestException: Invalid mapping expression specified: Validation Result: warnings : [], errors : [Invalid mapping expression parameter specified: method.response.header.Access-Control-Allow-Methods] (Service: null; Status Code: 400; Error Code: null; Request ID: xxxxxx-xxxx-xxxx-xxxxxxxxxx)
  • 原因
    API GatewayでCORSリクエストを許可するためレスポンスヘッダの設定を入れてたんですが、それがインポート時にうまく処理されてないみたい?
    ※CORSの設定は公式ドキュメントより補足のあるクラスメソッドさんの記事がわかりやすいです。
    (参考:Amazon API Gateway をクロスオリジンで呼び出す (CORS)
    さらに、この時はCORSは不要になったのでAWSコンソールからヘッダ設定を削除したんですが、エクスポートしたファイルにはなぜかヘッダが残っている状態。
    結局swaggerファイルから直接以下の行を削除してインポートしたらうまくいきました。
swagger.yaml
            responseParameters:
              method.response.header.Access-Control-Allow-Methods: "'GET,OPTIONS'"
              method.response.header.Access-Control-Allow-Headers: "'Content-Type,X-Amz-Date,Authorization,X-Api-Key'"
              method.response.header.Access-Control-Allow-Origin: "'*'"

追記:
これはIntegration ResponseHeader Mappingsから該当ヘッダを削除する前に、Method Responseのヘッダを削除してしまったために発生していた現象でした。
エクスポートしたファイルにヘッダの定義はないのにintegration側にヘッダ設定が残っていて不整合が起きてたのが原因でした。
ヘッダを削除するときには先にマッピングしてる方から削除しましょう。
ヘッダがちゃんと定義されてる状態だとインポートもうまくいきました。

モデルの2階層目のpropertiesが消えている

こんな感じで定義してたモデルが、

{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "user": {
      "type": "object",
      "properties": {
        "userId": {
          "type": "string"
        },
        "userName": {
          "type": "string"
        }
      }
    }
  }
}

インポートするとこんな感じになります。

{
  "definitions": {},
  "type": "object",
  "properties": {
    "user": {
      "type": "object"
    }
  }
}

要するに2階層目のpropetiesがインポートされてない(エクスポートされたファイルには入っている)。
API Gatewayのドキュメントを見る限りだと2階層の定義もされてるんですが、これはJSON SchemaのルールだとNGなのかも?
未解決なので時間とってちゃんと調べたい。

パスの最上階層に/{stage-name}が入っている

  • 原因
    これはAPI GatewayからエクスポートするとswaggerのbasePathパラメータにStage名が入ってるんですが、インポートの際にはこれをAPIの基底パスとして認識するため発生してます。
    Stage名が不要な場合は以下のようにエクスポートしたswaggerのbasePathを変更しましょう。
swagger.yaml
basePath: "/prod"

basePath: "/"
22
17
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
22
17