API Gateway の OpenAPI 2.0 拡張機能
API Gateway は、ゲートウェイの動作を構成する OpenAPI 仕様に対する Google 固有の拡張機能のセットを受け入れます。このページでは、バックエンド ルーティング、認証、API 管理機能などの API Gateway の動作を構成するために使用される、Google 独自の OpenAPI 仕様 2.0 のカスタム拡張機能について説明します。
例は YAML 形式で示されていますが、JSON もサポートされています。
命名規則
Google の OpenAPI 仕様拡張には、x-google- 接頭辞で始まる名前が付けられています。
x-google-allow
x-google-allow: [configured | all]
この拡張機能は、OpenAPI 仕様のトップレベルで使用され、API Gateway で許可される URL パスを示します。
有効な値は configured と all です。
デフォルト値は configured です。これは、OpenAPI 仕様にリストされている API メソッドのみが API Gateway を介して提供されることを意味します。
all を使用すると、API キーまたはユーザー認証の有無にかかわらず、構成されていない呼び出しが API Gateway を介して API に渡されます。
API Gateway は、API への呼び出しを大文字と小文字を区別して処理します。たとえば、API Gateway は /widgets と /Widgets を異なる API メソッドと見なします。
all が使用された場合、次の 2 点に関して注意が必要です。
- すべての API キーまたは認証ルール。
- サービスのバックエンド パス ルーティング。
ベスト プラクティスとして、大文字と小文字を区別するパス ルーティングを使用するように API を構成することをおすすめします。大文字と小文字を区別するルーティングを使用すると、URL でリクエストされたメソッドが OpenAPI 仕様にリストされている API メソッドと一致しない場合、HTTP ステータス コード 404 が返されます。Node.js Express などのウェブ アプリケーション フレームワークには、大文字と小文字を区別するルーティングを有効 / 無効にする設定があります。デフォルトの動作は使用しているフレームワークによって異なります。フレームワークの設定で、大文字と小文字を区別するルーティングが有効になっているか確認することをおすすめします。この推奨事項は、OpenAPI 仕様 v2.0 に記載されている「仕様内のすべてのフィールド名は大文字と小文字を区別する」と一致しています。
例
以下を想定しています。
x-google-allowはallに設定されている。- OpenAPI 仕様には API メソッド
widgetsがリストされているが、Widgetsはされていない。 - API キーを必要とする OpenAPI 仕様を構成している。
OpenAPI 仕様に widgets がリストされているため、API Gateway は API キーがない次のリクエストをブロックします。
https://my-project-id.appspot.com/widgets
Widgets が OpenAPI 仕様にリストされていないため、API Gateway は 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_audience または disable_auth のいずれも指定していない場合、API Gateway は jwt_audience を address と一致するように自動的にデフォルト設定します。address が設定されていない場合、API Gateway は disable_auth を true に自動的に設定します。
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)を使用して次のことができます。
- 特別な
allUsersプリンシパルからroles/run.invokerを取り消して、認証されていない呼び出しを制限します。 - API Gateway ランタイム サービス アカウントに
roles/run.invokerロールを付与して、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 は次の処理を行います。
- 元の値を新しいヘッダー
X-Forwarded-Authorizationにコピーします。 - インスタンス ID トークンで
Authorizationヘッダーをオーバーライドします。
したがって、API クライアントが Authorization ヘッダーを設定した場合、API Gateway の背後で実行されているバックエンドは X-Forwarded-Authorization ヘッダーを使用して JWT 全体を取得する必要があります。API Gateway は認証方法が構成されていない場合、検証を行わないため、バックエンドはこのヘッダーの JWT を検証する必要があります。
構成例については、API 構成を作成するをご覧ください。
disable_auth
disable_auth: bool
省略可。このプロパティは、API Gateway がインスタンス ID トークンの取得を防止し、リクエストへの添付を防止するかどうかを決定します。
次のいずれかの条件に該当する場合は、ターゲット バックエンドの構成時に、API Gateway からのリクエストの認証に IAP または IAM を使用しないようにします。
- バックエンドで未認証の呼び出しを許可する必要があります。
- バックエンドには 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
省略可。リクエストに対する完全な応答を待機する秒数。構成された期限よりも時間がかかるレスポンスはタイムアウトします。SSE またはチャンク転送エンドポイントでは、期限はストリーム全体の期間を制限しますが、gRPC または WebSocket エンドポイントでは、メッセージ間のギャップを制限します。各種類のリクエストに適用されるタイムアウトについては、ストリームの期限を設定するをご覧ください。デフォルトの期限は 15.0 秒です。
正でない値は無視されます。このような場合、API Gateway はデフォルト値を自動的に使用します。
期限は最大 3600 秒まで構成できます。非ストリーミング ゲートウェイでは、最大 600 秒のより低い上限が適用され、API 構成の作成時ではなく、ゲートウェイの作成または更新時に、より長い期限が拒否されます。
protocol
protocol: [ http/1.1 | h2 ]
省略可。バックエンドにリクエストを送信するために使用されるプロトコル。サポートされている値は http/1.1 と h2 です。
HTTP および HTTPS バックエンドのデフォルト値は http/1.1 です。
HTTP/2 をサポートするセキュア HTTP バックエンド(https://)の場合は、パフォーマンス改善のために、このフィールドを h2 に設定します。これは、 Google Cloud サーバーレス バックエンドに推奨されるオプションです。
プロトコルの要件は、ストリーミング タイプによって異なります。
- gRPC: プロトコルを
h2に設定する必要があります。 - WebSockets:
http/1.1を使用する必要があります。 - サーバー送信イベント(SSE)と増分レスポンス配信:
http/1.1またはh2のいずれかを使用できます。パフォーマンスを改善するため、h2をおすすめします。
パス変換について
API ゲートウェイはリクエストを処理する際に、元のリクエスト パスを取得して変換してから、ターゲット バックエンドにリクエストを送信します。この変換がどのように行われるかは、使用しているパス変換方法によって異なります。パス変換には次の 2 つの方法があります。
APPEND_PATH_TO_ADDRESS: ターゲットのバックエンド リクエストパスは、元のリクエストパスをaddressの URLx-google-backend拡張子に付加して計算されます。CONSTANT_ADDRESS: ターゲット リクエスト パスは、x-google-backend拡張機能のaddressURL で定義されているため、一定です。対応する OpenAPI パスにパラメータが含まれている場合、パラメータ名とその値はクエリ パラメータとなります。
例:
APPEND_PATH_TO_ADDRESSaddress: 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 パスパラメータを使用しない場合。
- OpenAPI パス:
/hello - リクエストパス:
/hello - ターゲット リクエスト URL:
https://my-project-id.appspot.com/BASE_PATH/hello
- OpenAPI パス:
CONSTANT_ADDRESSaddress: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 パスパラメータを使用しない場合。
- OpenAPI パス:
/hello - リクエストパス:
/hello - ターゲット リクエスト URL:
https://us-central1-my-project-id.cloudfunctions.net/helloGET
- OpenAPI パス:
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 サービスの表示名と一貫性を保つため、次のような表示名を使用することをおすすめします。
|
| 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}」のみがサポートされています。これは、上限がプロジェクトごとに適用され、使用量が毎分リセットされることを意味します。 |
| 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。
|
割り当ての例
次の例は、読み取りリクエストと書き込みリクエストに指標と制限を追加する方法を示しています。
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 に独立したバージョニングを確立できます。
たとえば、次の OpenAPI ドキュメント フラグメントを使用して、api.example.com という名前のサービスを 2 つの API(producer と consumer)で構成できます。
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