ポリシーおよびHTTPバック・エンド定義へのコンテキスト変数の追加

Find out how to use parameters in API calls using API Gateway context variables.

APIゲートウェイにデプロイされたAPIへのコールには、通常、APIデプロイメント仕様で次のような定義を行うときに使用するパラメータが含まれています:

  • リクエスト・ポリシーとレスポンス・ポリシー
  • HTTPおよびHTTPSバック・エンド

APIコールに含まれるパラメータを使用可能にするため、APIゲートウェイ・サービスでは、次のタイプのパラメータの値が一時'コンテキスト表'に保存されます:

コンテキスト表内の各レコードは、一意キーによって識別されます。

リクエスト・ポリシー、レスポンス・ポリシー、HTTPおよびHTTPSバック・エンドを定義する際、'コンテキスト変数'を使用してコンテキスト表のパラメータ値を参照できます。コンテキスト変数のフォーマットは<context-table-name>[<key>]で、説明は次のとおりです:

  • <context-table-name>は、request.pathrequest.queryrequest.headersrequest.authrequest.certまたはrequest.hostのいずれかです。
  • <key>は次のいずれかです:
    • APIデプロイメント仕様で定義されたパス・パラメータ名
    • APIへのリクエストに含まれる問合せパラメータ名
    • APIへのリクエストに含まれるヘッダー名
    • 認可プロバイダ・ファンクションによって返される、またはJWTトークンに含まれる認証パラメータ名
    • the name [client_base64], representing a successfully validated, Base64-encoded, certificate presented by an API client during an mTLS handshake
    • 無視するホスト名の末尾の部分(元のリクエストが送信されたホスト名の先頭部分を取得する場合)
    • リクエストの送信先ホストの名前(リクエストのHostヘッダー・フィールドから抽出)

文字列内のコンテキスト変数をAPIデプロイメント仕様(たとえば、HTTPバック・エンド定義のURLプロパティ)に含める場合は、${<context-table-name>[<key>]}というフォーマットを使用します。

たとえば、次の例のrequest.path[region]コンテキスト変数は、request.pathコンテキスト表のregionキーで識別されるレコードの値を戻します。

{
  "routes": [
    {
      "path": "/weather/{region}",
      "methods": ["GET"],
      "backend": {
        "type": "HTTP_BACKEND",
        "url": "https://api.weather.gov/${request.path[region]}"
      }
    }
  ]
}

次に注意してください:

  • HTTPリクエストの個別パラメータごとに、コンテキスト表に単一レコードが作成されます。HTTPリクエストに同じタイプおよび同じ名前の2つ(または、それ以上)のパラメータが含まれている場合、その名前の各パラメータの値はコンテキスト表の同じレコードに保存され、同じキーで識別されます。ただし、コンテキスト変数のかわりに置換できるのは、コンテキスト表レコードの最初の値のみです。コンテキスト表レコードに複数の値が存在できるコンテキスト変数を追加し、コンテキスト変数のかわりにコンテキスト表レコードの最初の値を置換する場合は、${<context-table-name>[<key>]}のフォーマットでAPIデプロイメント仕様にコンテキスト変数を追加します
  • パラメータ値にエンコーディングされている特殊文字が含まれている場合、その値がコンテキスト表に保存されるときにエンコーディングが保持されます。値がコンテキスト変数に置換されると、エンコーディングされた値はコンテキスト変数のかわりに置換されます。たとえば、San Joséが問合せパラメータにSan+Jos&#233;として含まれている場合、エンコーディングされたバージョンはその問合せパラメータのコンテキスト変数のかわりに置換されます。
  • 指定されたコンテキスト表にコンテキスト変数キーが存在しない場合は、コンテキスト変数のかわりに空の文字列が置換されます。
  • コンテキスト変数キーにドットが含まれている場合、ドットは他の文字として扱われます。その両側の文字列の親子関係を示すものとしては扱われません。
  • パス・パラメータにワイルドカード(たとえば、generic_welcome*)が含まれている場合は、ワイルドカードが含まれていないパス・パラメータがキーとして使用されます。
  • コンテキスト変数は、HTTPバック・エンド定義のURLプロパティにパス・セグメントとして含めることができますが、問合せパラメータとして含めることはできません。例:

    • 次の有効なHTTPバック・エンド定義に示すように、request.query[state]コンテキスト変数をURLプロパティのパス・セグメントとして使用できます:

            {
              "path": "/weather/{region}",
              "methods": ["GET"],
              "backend": {
                "type": "HTTP_BACKEND",
                "url": "https://api.weather.gov/${request.path[region]}/${request.query[state]}"
              }
            }
    • 次の無効なHTTPバック・エンド定義に示すように、request.query[state]コンテキスト変数をURLプロパティの問合せパラメータとして使用できません:

            {
              "path": "/weather/{region}",
              "methods": ["GET"],
              "backend": {
                "type": "HTTP_BACKEND",
                "url": "https://api.weather.gov/${request.path[region]}?state=${request.query[state]}"
              }
            }

    If you do want to pass a context variable as a query parameter, use a query parameter transformation request policy rather than including the context variable as a query parameter in the URL property (see Adding Query Parameter Transformation Request Policies).

このセクションの例では、JSONファイルの次のAPIデプロイメント定義および基本的なAPIデプロイメント仕様を想定しています:

{
  "displayName": "Marketing Deployment",
  "gatewayId": "ocid1.apigateway.oc1..aaaaaaaab______hga",
  "compartmentId": "ocid1.compartment.oc1..aaaaaaaa7______ysq",
  "pathPrefix": "/marketing",
  "specification": {
    "routes": [
      {
        "path": "/weather",
        "methods": ["GET"],
        "backend": {
          "type": "HTTP_BACKEND",
          "url": "https://api.weather.gov"
        }
      }
    ]
  },
  "freeformTags": {},
  "definedTags": {}
}

コンソールでダイアログを使用してAPIデプロイメント仕様を定義する場合も、例が適用されます。

例1: 定義内の問合せパス・パラメータ

APIデプロイメント仕様でパス・パラメータを定義し、APIデプロイメント仕様の任意の場所でコンテキスト変数として使用できます。

この例では、パス・パラメータregionを作成し、HTTPバック・エンド定義のコンテキスト変数request.path[region]に使用します。

      {
        "path": "/weather/{region}",
        "methods": ["GET"],
        "backend": {
          "type": "HTTP_BACKEND",
          "url": "https://api.weather.gov/${request.path[region]}"
        }
      }

この例では、https://<gateway-hostname>/marketing/weather/westのようなリクエストがhttps://api.weather.gov/westに解決されます。

例2: 同じ定義の異なるタイプのコンテキスト変数

APIデプロイメント仕様の同じ定義に、様々なタイプのコンテキスト変数を含めることができます。

この例では、HTTPバック・エンド定義で次を使用します:

  • パス・パラメータのコンテキスト変数request.path[region]
  • 問合せパラメータのコンテキスト変数request.query[state]
      {
        "path": "/weather/{region}",
        "methods": ["GET"],
        "backend": {
          "type": "HTTP_BACKEND",
          "url": "https://api.weather.gov/${request.path[region]}/${request.query[state]}"
        }
      }

この例では、https://<gateway-hostname>/marketing/weather/west?state=californiaのようなリクエストがhttps://api.weather.gov/west/californiaに解決されます。

例3: 同じ定義の同じタイプの複数のコンテキスト変数

同じタイプのコンテキスト変数を同じ定義に複数回含めることができます。

この例では、HTTPバック・エンド定義で次を使用します:

  • パス・パラメータのコンテキスト変数request.path[region]
  • 2つの問合せパラメータのコンテキスト変数、request.query[state]およびrequest.query[city]
      {
        "path": "/weather/{region}",
        "methods": ["GET"],
        "backend": {
          "type": "HTTP_BACKEND",
          "url": "https://api.weather.gov/${request.path[region]}/${request.query[state]}/${request.query[city]}"
        }
      }

この例では、https://<gateway-hostname>/marketing/weather/west?state=california&city=fremontのようなリクエストがhttps://api.weather.gov/west/california/fremontに解決されます。

例4: 同じパラメータに対する複数の値

多くの場合、HTTPリクエストに同じ問合せパラメータを複数回含めることは有効です。APIゲートウェイ・サービスは、各パラメータの値をコンテキスト表の同じレコードに同じ名前で保存します。ただし、APIデプロイメント仕様では、通常、コンテキスト変数に置換できる値は1つのみです。このような場合、${...}内にコンテキスト変数を囲むことによって、コンテキスト表でキーに対して記録された最初の値のみが、コンテキスト変数のかわりに置換されることを示すことができます。

たとえば、"https://<gateway-hostname>/marketing/weather/west?state=california&city=fremont&city=belmont"などの有効なリクエストに、city問合せパラメータが2つ発生します。HTTPリクエストを受信すると、APIゲートウェイ・サービスによってcity問合せパラメータ(fremontおよびbelmont)の値が、request.query表の同じレコードに書き込まれます。HTTPバック・エンドの定義に${request.query[city]}が含まれる場合、レコードの最初の値のみがコンテキスト変数のかわりに置換されます。

この例では、HTTPバック・エンド定義で次を使用します:

  • パス・パラメータのコンテキスト変数request.path[region]
  • 2つの問合せパラメータのコンテキスト変数、request.query[state]およびrequest.query[city]
      {
        "path": "/weather/{region}",
        "methods": ["GET"],
        "backend": {
          "type": "HTTP_BACKEND",
          "url": "https://api.weather.gov/${request.path[region]}/${request.query[state]}/${request.query[city]}"
        }
      }

この例では、https://<gateway-hostname>/marketing/weather/west?state=california&city=fremont&city=belmontのようなリクエストがhttps://api.weather.gov/west/california/fremontに解決されます。cityキーで識別されるrequest.queryコンテキスト表レコードの最初の値として、fremontのみがrequest.query[city]コンテキスト変数に置換されることに注意してください。

例5: パラメータ値にエンコーディングされた特殊文字が含まれる

HTTPリクエストにエンコーディングされている特殊文字(たとえば、文字é、スペース文字)が含まれる場合、値はエンコーディングされた形式でコンテキスト表に格納されます。コンテキスト変数にコンテキスト表の値が置換される場合、エンコーディングは保持されます。

この例では、HTTPバック・エンド定義で次を使用します:

  • パス・パラメータのコンテキスト変数request.path[region]
  • 問合せパラメータのコンテキスト変数request.query[city]
      {
        "path": "/weather/{region}",
        "methods": ["GET"],
        "backend": {
          "type": "HTTP_BACKEND",
          "url": "https://api.weather.gov/${request.path[region]}/${request.query[state]}/${request.query[city]}"
        }
      }

この例では、https://<gateway-hostname>/marketing/weather/west?city=San+Jos&#233;のようなリクエストがhttps://api.weather.gov/west/california/San+Jos&#233;に解決されます。

例6: 定義内のヘッダー・パラメータ

リクエストのヘッダーに渡される値を、定義のコンテキスト変数として含めることができます。リクエストにヘッダーが含まれる場合、ヘッダーの値はrequest.headers表に格納され、ヘッダーの名前がキーとして使用されます。

この例では、HTTPバック・エンド定義で次を使用します:

  • パス・パラメータのコンテキスト変数request.path[region]
  • ヘッダー・パラメータのコンテキスト変数request.headers[X-Api-Key]
      {
        "path": "/weather/{region}",
        "methods": ["GET"],
        "backend": {
          "type": "HTTP_BACKEND",
          "url": "https://api.weather.gov/${request.path[region]}/${request.headers[X-Api-Key]}"
        }
      }

この例では、https://<gateway-hostname>/marketing/weather/westのようなリクエストに、値がabc123def456fhi789X-Api-Keyヘッダーが含まれています。リクエストはhttps://api.weather.gov/west/abc123def456fhi789に解決されます。

例7: 定義内の認証パラメータ

認可プロバイダ・ファンクションから返された値、またはJWTトークンにコンテキスト変数として含まれている値を定義に含めることができます:

  • 認可プロバイダ・ファンクションは、APIゲートウェイ・サービスのコール時にAPIクライアントから渡されたトークンを検証します。認可プロバイダ・ファンクションは、認可の有効性、エンド・ユーザーの情報、アクセス・スコープ、いくつかのクレームなどの情報をキーと値のペアの形式で含むレスポンスを返します。認可トークンによっては、情報がトークンに含まれている場合もあれば、認可プロバイダ・ファンクションが認可サーバーから提供されたエンドポイントを呼び出して、トークンを検証し、エンド・ユーザーの情報を取得する場合もあります。APIゲートウェイ・サービスが認可プロバイダ・ファンクションからキーと値のペアを受信すると、request.auth表にキーと値のペアを認証パラメータとして保存します。
  • JWTトークンには、オプションで、キーと値のペアで構成されるscopeという名前のカスタム・クレームを含めることができます。JWTトークンが検証されると、APIゲートウェイ・サービスはキーと値のペアを認証パラメータとしてrequest.auth表に保存します。

    In the case of the OpenID Connect authorization flow, two tokens named id_token (always JWT-encoded) and access_token (can be JWT-encoded) are returned. The API Gateway service saves the token values in the request.auth[id_token] and request.auth[access_token] context variables, along with custom claims in the request.auth[id_token_claims][<claim-name>] and request.auth[access_token_claims][<claim-name>] context variables respectively.

この例では、認可プロバイダ・ファンクションによって返されるキーと値のペアを、HTTPバック・エンド定義の認証パラメータ・コンテキスト変数request.auth[region]として使用します。

  {
    "requestPolicies": {
      "authentication": {
        "type": "CUSTOM_AUTHENTICATION",
        "isAnonymousAccessAllowed": false,
        "functionId": "ocid1.fnfunc.oc1.phx.aaaaaaaaac2______kg6fq",
        "tokenHeader": "Authorization"
      }
    },
    "routes": [
      {
        "path": "/weather",
        "methods": ["GET"],
        "backend": {
          "type": "HTTP_BACKEND",
          "url": "https://api.weather.gov/${request.auth[region]}"
        },
        "requestPolicies": {
          "authorization": {
            "type": "ANY_OF",
            "allowedScope": [ "weatherwatcher" ]
          }
        }
      }
    ]
  }

認可プロバイダ・ファンクションocid1.fnfunc.oc1.phx.aaaaaaaaac2______kg6fqが、APIゲートウェイ・サービスのコールでAPIクライアントから渡されたトークンを検証するとします。認可プロバイダ・ファンクションは、エンド・ユーザーに関連付けられたリージョン(キーと値のペア)および認証済エンド・ユーザーのアクセス・スコープを含むレスポンスをAPIゲートウェイ・サービスに返します。APIゲートウェイ・サービスがキーと値のペアを受信すると、request.auth表にキーと値のペアを認証パラメータとして保存します。

この例では、エンド・ユーザーjdoeがAPIクライアントを使用して、https://<gateway-hostname>/marketing/weatherのようなリクエストを発行します。認可プロバイダ・ファンクションは、リクエストでAPIクライアントから渡されたトークンを検証し、jdoeがアクセス・スコープ"weatherwatcher"を持つことを確認します。認可プロバイダ・ファンクションは、jdoeが西部リージョンに関連付けられていることを識別します。認可プロバイダ・ファンクションは、jdoeのアクセス・スコープをAPIゲートウェイ・サービスに返し、jdoeに関連付けられたリージョンも返します。APIゲートウェイ・サービスは、jdoeに関連付けられたリージョンを認証パラメータとして保存します。HTTPバック・エンド定義では、アクセス・スコープ"weatherwatcher"を持つエンド・ユーザーにHTTPバック・エンドへのアクセスを許可することを指定します。APIゲートウェイ・サービスは、リクエストで認証パラメータのコンテキスト変数request.auth[region]の値を使用します。リクエストはhttps://api.weather.gov/westに解決されます。

Example 8: TLS certificate parameter in a definition

You can include a Base64-encoded version of the TLS certificate presented by an API client during an mTLS handshake as a context variable in a definition. The Base64-encoded version of the TLS certificate is stored in the request.cert table, with the name client_base64 used as the key. See Adding mTLS support to API Deployments.

この例では、HTTPバック・エンド定義で次を使用します:

  • 証明書コンテキスト変数request.cert[client_base64]
  {
    "requestPolicies": {
      "mutualTls":{
        "isVerifiedCertificateRequired": true,
        "allowedSans": ["api.weather.com"]
      }
    },
    "routes": [
      {
        "path": "/weather",
        "methods": ["GET"],
        "backend": {
          "type": "HTTP_BACKEND",
          "url": "https://api.weather.gov"
        },
        "requestPolicies": {
          "headerTransformations": {
            "setHeaders": {
              "items":[
                {
                  "name": "certificate-header",
                  "values": ["${request.cert[client_base64]}"]
                }
              ]
            }
          }
        }
      }
    ]
  }

In this example, a header named certificate-header is added to the request, and given the value of the Base64-encoded version of the TLS certificate presented by the API client during the mTLS handshake with the API gateway.