API Gateway の OpenAPI 2.0 拡張機能

API Gateway では、ゲートウェイの動作を構成するために Google が独自に開発した OpenAPI 仕様の拡張機能がサポートされています。このページでは、バックエンド ルーティング、認証、API 管理機能などの API Gateway の動作を構成するために使用される、OpenAPI 仕様 2.0 の Google 固有のカスタム拡張機能について説明します。

以下の例は YAML 形式ですが、JSON もサポートされています。

命名規則

Google の OpenAPI 仕様拡張には、x-google- 接頭辞で始まる名前が付けられています。

x-google-allow

x-google-allow: [configured | all]

この拡張機能は、OpenAPI 仕様の最上位で使用し、API Gateway で許可される URL パスを指定します。

有効な値は configuredall です。

デフォルト値は configured で、OpenAPI 仕様にある API メソッドだけが API Gateway 経由で提供されます。

all を使用すると、(API キーやユーザー認証の有無に関係なく)未構成の呼び出しは API Gateway を通過して API に到達します。

API Gateway では API の呼び出しが大文字と小文字を区別して処理されます。たとえば、/widgets/Widgets は異なる API メソッドと見なされます。

all が使用された場合、次の 2 点に関して注意が必要です。

  • すべての API キーまたは認証ルール。
  • サービスのバックエンド パス ルーティング。

ベスト プラクティスとして、大文字と小文字を区別するパス ルーティングを使用するように API を構成することをおすすめします。大文字と小文字を区別するルーティングを使用すると、URL でリクエストされたメソッドが OpenAPI 仕様にリストされている API メソッドと一致しない場合、HTTP ステータス コード 404 が返されます。Node.js Express などのウェブ アプリケーション フレームワークには、大文字と小文字を区別するルーティングを有効 / 無効にする設定があります。デフォルトの動作は使用しているフレームワークによって異なります。フレームワークの設定で、大文字小文字を区別するルーティングが有効になっているか確認することをおすすめします。この推奨事項は、OpenAPI 仕様 v2.0 に記載されている「仕様内のすべてのフィールド名は大文字と小文字を区別する」と一致しています。

以下を想定しています。

  • x-google-allowall に設定されている。
  • OpenAPI 仕様には API メソッド widgets がリストされているが、Widgets はされていない。
  • API キーを必要とする OpenAPI 仕様を構成している。

widgets は OpenAPI 仕様にリストされており、API キーがないため、次のリクエストは API Gateway でブロックされます。

https://my-project-id.appspot.com/widgets

Widgets は OpenAPI 仕様にリストされていないため、次のリクエストは API キーなしでサービスに渡されます。

https://my-project-id.appspot.com/Widgets/

API で大文字小文字を区別するルーティングを使用している(また「Widgets」の呼び出しをどのコードにもルーティングしていない)場合、API のバックエンドは 404 を返します。ただし、大文字小文字を区別しないルーティングを使用している場合、API バックエンドはこの呼び出しを「widgets」にルーティングします。

言語やフレームごとに、大文字小文字の区別とルーティングを制御する方法が異なります。詳細については、フレームワークのドキュメントをご覧ください。

x-google-backend

x-google-backend 拡張機能は、リクエストをリモート バックエンドに転送する方法を指定します。この拡張機能は、OpenAPI 仕様のトップレベル、オペレーション レベル、または両方のレベルで指定できます。

x-google-backend 拡張機能では、リモート バックエンドの他の設定(認証やタイムアウトなど)も構成できます。これらの構成はすべて、オペレーションごとに適用できます。

x-google-backend 拡張機能には以下のフィールドが含まれます。

address

address: URL

必須。ターゲット バックエンドの URL。 アドレスのスキームは http または https のいずれかである必要があります。

リモート バックエンド(サーバーレス)へのルーティング時は、アドレスを設定し、スキーム部分は https にします。

jwt_audience | disable_auth

これらの 2 つのプロパティの 1 つのみを設定する必要があります。

オペレーションで x-google-backend を使用するものの、jwt_audiencedisable_auth を指定しない場合、API Gateway では address に一致する jwt_audience が自動的に設定されます。address が設定されていない場合、API Gateway は自動的に disable_authtrue に設定します。

jwt_audience

jwt_audience: string

省略可。API Gateway がインスタンス ID トークンを取得すると、JWT オーディエンスが指定され、ターゲット バックエンド リクエストの際に使用されます。

サーバーレス用に API Gateway を構成する場合は、リモート バックエンドを保護して、API Gateway からのトラフィックのみを許可する必要があります。API Gateway は、リクエストをプロキシ処理するときにインスタンス ID トークンを Authorization ヘッダーに添付します。インスタンス ID トークンは、API Gateway のデプロイに使用されたランタイム サービス アカウントを表します。リモート バックエンドは、この添付されたトークンに基づいて、リクエストが API Gateway からのものであることを確認できます。

たとえば、Cloud Run にデプロイされたリモート バックエンドは、Identity and Access Management(IAM)を使用して次のことができます。

  1. 特別な allUsers プリンシパルから roles/run.invoker を取り消して、認証されていない呼び出しを制限します。
  2. roles/run.invoker ロールを API Gateway ランタイム サービス アカウントに付与して、API Gateway にのみバックエンドの呼び出しを許可します。

デフォルトでは、API Gateway は address フィールドと一致する JWT オーディエンスを使用してインスタンス ID トークンを作成します。jwt_audience を手動で指定するのは、ターゲット バックエンドが JWT ベースの認証を使用し、想定されるオーディエンスが address フィールドで指定された値と異なる場合のみ必要になります。App Engine にデプロイされたリモート バックエンドまたは Identity-Aware Proxy(IAP)を使用するリモート バックエンドの場合は、JWT オーディエンスをオーバーライドする必要があります。App Engine と IAP は、OAuth クライアント ID を想定されるオーディエンスとして使用します。

この機能を有効にすると、API Gateway はリクエスト内のヘッダーを変更します。リクエストにすでに Authorization ヘッダーが設定されている場合、API Gateway は次のようにします。

  1. 元の値を新しいヘッダー X-Forwarded-Authorization にコピーします。
  2. インスタンス ID トークンで Authorization ヘッダーをオーバーライドします。

したがって、API クライアントが Authorization ヘッダーを設定する場合、API Gateway の背後で実行中のバックエンドは X-Forwarded-Authorization ヘッダーを使用して JWT 全体を取得する必要があります。認証方法が構成されていない場合、API Gateway は検証を行わないため、バックエンドがこのヘッダーで JWT を検証する必要があります

構成例については、API 構成を作成するをご覧ください。

disable_auth

disable_auth: bool

省略可。このプロパティは、API Gateway がインスタンス ID トークンの取得を禁止し、リクエストへのアタッチを禁止すべきかどうかを決定します。

ターゲット バックエンドを構成する際、次のいずれかの条件に該当する場合、IAP または IAM を使用して API Gateway からのリクエストの認証を行うことはできません。

  1. バックエンドは未認証の呼び出しを許可する必要があります。
  2. バックエンドには API クライアントからの元の Authorization ヘッダーが必要であり、X-Forwarded-Authorization は使用できません(jwt_audience のセクションで説明)。

この場合は、このフィールドを true に設定します。

path_translation

path_translation: [ APPEND_PATH_TO_ADDRESS | CONSTANT_ADDRESS ]

省略可。ターゲット バックエンドにリクエストをプロキシするときに API Gateway が使用するパス変換ストラテジを設定します。

パス変換の詳細については、パス変換についてをご覧ください。

x-google-backend が OpenAPI 仕様の最上位レベルで使用される場合、path_translation のデフォルトは APPEND_PATH_TO_ADDRESS になり、x-google-backend が OpenAPI 仕様のオペレーション レベルで使用される場合、path_translation のデフォルトは CONSTANT_ADDRESS になります。address フィールドがない場合、path_translation は未指定のままになり、検出されません。

deadline

deadline: double

省略可。リクエストに対する完全な応答を待機する秒数。構成された期限よりも時間がかかる応答はタイムアウトします。デフォルトの期限は 15.0 秒です。

正でない値は受け入れられません。その場合、API Gateway では自動的にデフォルト値が使用されます。

期限を無効にすることはできませんが、たとえば 600 秒(最大期限)などの高い数値に設定することは可能です。

protocol

protocol: [ http/1.1 | h2 ]

省略可。バックエンドにリクエストを送信するために使用されるプロトコル。サポートされている値は http/1.1h2 です。

HTTP および HTTPS バックエンドのデフォルト値は http/1.1 です。

HTTP/2 をサポートするセキュア HTTP バックエンド(https://)の場合は、パフォーマンス改善のために、このフィールドを h2 に設定します。これは、 Google Cloud サーバーレス バックエンドに推奨されるオプションです。

パス変換について

API Gateway はリクエストを処理すると、ターゲット バックエンドにリクエストする前に元のリクエストパスを受け取り変換します。この変換がどのように行われるかは、使用しているパス変換方法によって異なります。パス変換には次の 2 つの方法があります。

  • APPEND_PATH_TO_ADDRESS: ターゲットのバックエンド リクエストパスは、元のリクエストパスを address の URL x-google-backend 拡張子に付加して計算されます。
  • CONSTANT_ADDRESS: x-google-backend 拡張子の address URL によって定義されるため、ターゲットのリクエストパスは定数となります。対応する OpenAPI パスにパラメータが含まれている場合、パラメータ名とその値はクエリ パラメータとなります。

例:

  • APPEND_PATH_TO_ADDRESS
    • address: https://my-project-id.appspot.com/BASE_PATH
    • OpenAPI パスパラメータ
        を使用する場合
      • OpenAPI パス: /hello/{name}
      • リクエストパス: /hello/world
      • ターゲット リクエスト URL: https://my-project-id.appspot.com/BASE_PATH/hello/world
    • OpenAPI パスパラメータを使用しない場合。
      • OpenAPI パス: /hello
      • リクエストパス: /hello
      • ターゲット リクエスト URL: https://my-project-id.appspot.com/BASE_PATH/hello
  • CONSTANT_ADDRESS
    • address: https://us-central1-my-project-id.cloudfunctions.net/helloGET
    • OpenAPI パスパラメータ
        を使用する場合
      • OpenAPI パス: /hello/{name}
      • リクエストパス: /hello/world
      • ターゲット リクエスト URL: https://us-central1-my-project-id.cloudfunctions.net/helloGET?name=world
    • OpenAPI パスパラメータを使用しない場合。
      • OpenAPI パス: /hello
      • リクエストパス: /hello
      • ターゲット リクエスト URL: https://us-central1-my-project-id.cloudfunctions.net/helloGET

x-google-endpoints

このセクションでは、x-google-endpoints 拡張子の使用方法について説明します。

CORS リクエストを許可するように API Gateway を構成する

別の異なるオリジンのウェブ アプリケーションから API が呼び出される場合、その API はクロスオリジン リソース シェアリング(CORS)をサポートする必要があります。CORS をサポートするように API Gateway を構成する方法については、API Gateway に CORS サポートを追加するをご覧ください。

カスタム CORS サポートをバックエンド コードに実装する必要がある場合は、API Gateway がすべての CORS リクエストをバックエンド コードに通過するように allowCors: True を設定します。

x-google-endpoints:
- name: "API_NAME.endpoints.PROJECT_ID.cloud.goog"
  allowCors: True

OpenAPI ドキュメントのトップレベル(インデントやネストのないレベル)の x-google-endpoints 拡張機能を追加します。例を次に示します。

swagger: "2.0"
host: "my-cool-api.endpoints.my-project-id.cloud.goog"
x-google-endpoints:
- name: "my-cool-api.endpoints.my-project-id.cloud.goog"
  allowCors: True

x-google-issuer

x-google-issuer: URI | EMAIL_ADDRESS

この拡張機能は、OpenAPI securityDefinitions セクションで認証情報の発行者を指定するために使用されます。ホスト名またはメールアドレスを指定します。

x-google-jwks_uri

x-google-jwks_uri: URI

JSON ウェブトークンの署名検証に使用されるプロバイダの公開鍵の URI です。

x-google-jwks_uri(OpenAPI 2.0)または jwksUri(OpenAPI 3.x)フィールドは必須です。API Gateway は、この OpenAPI 拡張で定義された次の 2 つの非対称公開鍵形式をサポートしています。

  • JWK セット形式 次に例を示します。

    OpenAPI 2.0

    x-google-jwks_uri: "https://YOUR_ACCOUNT_NAME.YOUR_AUTH_PROVIDER_URL/.well-known/jwks.json"
    

    OpenAPI 3.x

    jwksUri: "https://YOUR_ACCOUNT_NAME.YOUR_AUTH_PROVIDER_URL/.well-known/jwks.json"
    
  • X509次に例を示します。

    OpenAPI 2.0

    x-google-jwks_uri: "https://www.googleapis.com/service_accounts/v1/metadata/x509/securetoken@system.gserviceaccount.com"
    

    OpenAPI 3.x

    jwksUri: "https://www.googleapis.com/service_accounts/v1/metadata/x509/securetoken@system.gserviceaccount.com"
    

対称鍵形式を使用する場合は、Base64URL エンコードされた鍵文字列を含むファイルの URI に x-google-jwks_uri(OpenAPI 2.0)または jwksUri(OpenAPI 3.x)を設定します。

x-google-jwt-locations

デフォルトでは、JWT は Authorization ヘッダー(接頭辞 "Bearer ")、X-Goog-Iap-Jwt-Assertion ヘッダー、または access_token クエリ パラメータのいずれかで渡されます。

または、OpenAPI セキュリティ定義セクションの x-google-jwt-locations 拡張機能を使用して、JWTを使用して、JWT トークンを抽出する場所をカスタマイズします。

x-google-jwt-locations 拡張機能は、JWT ロケーションのリストを受け入れます。各 JWT ロケーションには、次のフィールドがあります。

要素 説明
header/query 必須。JWT を含むヘッダーの名前、または JWT を含むクエリ パラメータの名前です。
value_prefix 省略可。ヘッダーの場合のみ。value_prefix が設定されている場合、その値は JWT を含むヘッダー値の接頭辞と一致する必要があります。

次に例を示します。

x-google-jwt-locations:
  # Expect header "Authorization": "MyBearerToken <TOKEN>"
  - header: "Authorization"
    value_prefix: "MyBearerToken "
  # expect header "jwt-header-foo": "jwt-prefix-foo<TOKEN>"
  - header: "jwt-header-foo"
    value_prefix: "jwt-prefix-foo"
  # expect header "jwt-header-bar": "<TOKEN>"
  - header: "jwt-header-bar"
  # expect query parameter "jwt_query_bar=<TOKEN>"
  - query: "jwt_query_bar"

デフォルトのJWTロケーションのサブセットのみをサポートする場合は、x-google-jwt-locations 拡張機能で明示的にリストします。たとえば、"Bearer " 接頭辞を持つ Authorization ヘッダーのみのサポートを含める場合は以下のようにします。

  x-google-jwt-locations:
    # Support the default header "Authorization": "Bearer <TOKEN>"
    - header: "Authorization"
      value_prefix: "Bearer "

x-google-audiences

x-google-audiences: STRING

この拡張機能は、OpenAPI securityDefinitions セクションで使用され、JWT 認証中に JWT aud フィールドが一致する必要があるオーディエンスのリストを提供します。この拡張機能では、値をカンマで区切った単一の文字列を指定できます。ユーザー間をスペースで区切ることはできません。指定されていない場合、JWT aud フィールドは OpenAPI ドキュメントの host フィールドと一致する必要があります。

securityDefinitions:
  google_id_token:
    type: oauth2
    authorizationUrl: ""
    flow: implicit
    x-google-issuer: "https://accounts.google.com"
    x-google-jwks_uri: "https://www.googleapis.com/oauth2/v1/certs"
    x-google-audiences: "848149964201.apps.googleusercontent.com,841077041629.apps.googleusercontent.com"

x-google-management

x-google-management 拡張機能は API 管理のさまざまなアスペクトを制御します。このセクションでは、それらのフィールドについても説明します。

metrics

割り当てx-google-quota を組み合わせて metrics を使用し、API の割り当てを設定できます。割り当てでは、API でメソッドを呼び出すことのできるレートを制御できます。例:

x-google-management:
  metrics:
    - name: read-requests
      displayName: Read requests
      valueType: INT64
      metricKind: DELTA

metrics フィールドは、次の Key-Value ペアのリストで構成されます。

要素 説明
name 必須。この指標の名前。通常、これは指標を一意に識別するリクエストのタイプ(たとえば、「read-requests」または「write-requests」)です。
displayName

これは省略可能ですが、指定することをおすすめします。Google Cloud コンソールの [エンドポイント] > [サービス] ページの [割り当て] タブに表示される指標を表すテキスト。このテキストは、[IAM と管理] および [API とサービス] の [割り当て] ページで、API ユーザーに対しても表示されます。表示名の最大文字数は 40 文字です。

読みやすくするために、関連する割り当て上限の単位が、Google Cloud コンソールの表示名に自動的に追加されます。たとえば、表示名を「Read requests」にすると、Google Cloud コンソールには「Read requests per minute per project」と表示されます。これらを指定しない場合、[IAM と管理] および [API とサービス] の [割り当て] ページでは、API コンシューマに「ラベルなしの割り当て」が表示されます。

API コンシューマに表示される [割り当て] ページの Google サービスの表示名と一貫性を保つため、次のような表示名を使用することをおすすめします。

  • 指標が 1 つしかない場合は、「Requests」を使用する。
  • 指標が複数ある場合は、それぞれがリクエストのタイプを示し、「requests」という単語を含める(「read-requests」または「write-requests」など)。
  • 指標に関連するコストのいずれかが 1 より大きい場合、「requests」の代わりに割り当ての単位を使用する。
valueType 必須。「INT64」でなければなりません。
metricKind 必須。「DELTA」でなければなりません。

quota

quota セクションでは、定義済み指標の 割り当て 制限を指定します。例:

quota:
  limits:
    - name: read-requests-limit
      metric: read-requests
      unit: 1/min/{project}
      values:
        STANDARD: 5000

quota.limits フィールドは、次の Key-Value ペアになったリストで構成されます。

要素 説明
name 必須。制限の名前。サービス内で一意でなければなりません。この名前には、大文字小文字、数字、および「-」(ダッシュ文字)を含めることができ、最大長は 64 文字です。
指標 必須。この制限が適用される指標の名前。この名前は、指標の名前で指定されたテキストと一致する必要があります。指定されたテキストが指標名と一致しない場合は、OpenAPI ドキュメントのデプロイ時にエラーが発生します。
単位 必須。制限の単位。「1/min/{project}」のみがサポートされています。つまり、プロジェクトごとに制限が適用され、1 分ごとに使用率がリセットされます。
values 必須。指標の制限。これは、Key-Value ペアとして、次の形式で指定する必要があります。
STANDARD: YOUR-LIMIT-FOR-THE-METRIC
YOUR-LIMIT-FOR-THE-METRIC の代わりに、指定された単位で許可される最大リクエスト数の整数値を指定します。次に例を示します。
values:
  STANDARD: 5000

x-google-quota

API のメソッドを指標に関連付けるために、OpenAPI の paths セクションで x-google-quota 拡張機能を使用します。x-google-quota が定義されていないメソッドには割り当て上限が適用されません。例:

x-google-quota:
  metricCosts:
    read-requests: 1

x-google-quota 拡張機能は、次の項目で構成されます。

要素 説明
metricCosts ユーザー定義のキー: Key-Value ペア: "YOUR-METRIC-NAME": METRIC-COST
  • "YOUR-METRIC-NAME":: "YOUR-METRIC-NAME" のテキストは定義された指標名と一致する必要があります。
  • METRIC-COST:: 各リクエストのコストを定義する整数値。要求が行われると、関連する指標が指定されたコストで増分されます。コストを使用することによって、さまざまなメソッドから同じ指標を異なるレートで消費できます。たとえば、指標の割り当て上限が 1,000 で、コストが 1 の場合、呼び出し元のアプリケーションは、1 分間に 1,000 回のリクエストを行えます。同じ指標に対してコストが 2 に指定されると、呼び出し元のアプリケーションは、1 分間に 500 回のリクエストしか実行できません。

割り当ての例

次の例は、読み取りリクエストと書き込みリクエストに指標と制限を追加する方法を示しています。

x-google-management:
  metrics:
    # Define a metric for read requests.
    - name: "read-requests"
      displayName: "Read requests"
      valueType: INT64
      metricKind: DELTA
    # Define a metric for write requests.
    - name: "write-requests"
      displayName: "Write requests"
      valueType: INT64
      metricKind: DELTA
  quota:
    limits:
      # Rate limit for read requests.
      - name: "read-requests-limit"
        metric: "read-requests"
        unit: "1/min/{project}"
        values:
          STANDARD: 5000
      # Rate limit for write requests.
      - name: "write-request-limit"
        metric: "write-requests"
        unit: "1/min/{project}"
        values:
          STANDARD: 5000

paths:
  "/echo":
    post:
      description: "Echo back a given message."
      operationId: "echo"
      produces:
      - "application/json"
      responses:
        200:
          description: "Echo"
          schema:
            $ref: "#/definitions/echoMessage"
      parameters:
      - description: "Message to echo"
        in: body
        name: message
        required: true
        schema:
          $ref: "#/definitions/echoMessage"
      x-google-quota:
        metricCosts:
          read-requests: 1
      security:
      - api_key: []

x-google-api-name

サービスに含まれる API が 1 つのみの場合、API 名は API Gateway サービス名と同じになります。(API Gateway では、OpenAPI ドキュメントの host フィールドで指定した名前がサービスの名前として使用されます)。サービスに複数の API が含まれている場合、OpenAPI ドキュメントに x-google-api-name 拡張を追加して API 名を指定します。x-google-api-name 拡張機能を使用すると、個々の API に明示的に名前を付けて、API ごとに独立したバージョニングを確立できます。

たとえば、producer と consumer という 2 つの API で、次の OpenAPI ドキュメントのフラグメントを使用して api.example.com という名前のサービスを設定できます。

  • Producer API を定義する producer.yaml の例

    swagger: 2.0
    host: api.example.com
    x-google-api-name: producer
    info:
      version: 1.0.3
    

  • Consumer API を定義する consumer.yaml の例

    swagger: 2.0
    host: api.example.com
    x-google-api-name: consumer
    info:
      version: 1.1.0
    

次に、2 つの OpenAPI ドキュメントをまとめて次のようにデプロイできます。

gcloud api-gateway api-configs create API_CONFIG_ID \
  --api=my-api \
  --openapi-spec="producer.yaml,consumer.yaml" \
  --project=my-project-id