Adding Context Variables to Policies and HTTP Back End Definitions

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

Calls to APIs deployed on an API gateway typically include parameters that you'll want to use when defining the following in API deployment specifications:

  • request policies and response policies
  • HTTP and HTTPS back ends

To enable you to use parameters included in API calls, the API Gateway service saves the values of the following types of parameter in temporary 'context tables':

Each record in a context table is identified by a unique key.

When defining request and response policies, and HTTP and HTTPS back ends, you can reference the value of a parameter in a context table using a 'context variable'. A context variable has the format <context-table-name>[<key>] where:

  • <context-table-name> is one of request.path, request.query, request.headers, request.auth, request.cert, or request.host
  • <key> is one of:
    • a path parameter name defined in the API deployment specification
    • a query parameter name included in the request to the API
    • a header name included in the request to the API
    • an authentication parameter name returned by an authorizer function or contained in a JWT token
    • the name [client_base64], representing a successfully validated, Base64-encoded, certificate presented by an API client during an mTLS handshake
    • the trailing part of the host name to ignore (when capturing the leading part of the host name to which the original request was sent)
    • the name of a host to which the request was sent (extracted from the Host header field in the request)

If you want to include the context variable within a string in the API deployment specification (for example, in the url property of an HTTP back end definition), use the format ${<context-table-name>[<key>]}.

For example, the request.path[region] context variable in the example below returns the value of the record identified by the region key in the request.path context table.

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

Note the following:

  • A single record is created in the context table for each discrete parameter in an HTTP request. If the HTTP request includes two (or more) parameters of the same type and with the same name, the value of each parameter with that name is saved in the same record in the context table and identified by the same key. However, only the first value in the context table record can be substituted in place of a context variable. When adding a context variable for which multiple values can exist in the context table record and you want the first value in the context table record to be substituted in place of the context variable, add the context variable to the API deployment specification in the format ${<context-table-name>[<key>]}
  • If a parameter value includes special characters that have been encoded, the encoding is preserved when the value is saved in the context table. When the value is substituted for a context variable, the encoded value is substituted in place of the context variable. For example, if San José is included in a query parameter as San+Jos&#233;, the encoded version is what will be substituted in place of the context variable for that query parameter.
  • If a context variable key does not exist in the specified context table, an empty string is substituted in place of the context variable.
  • If a context variable key contains a dot, the dot is treated as any other character. It is not treated as an indicator of a parent-child relationship between the strings either side of it.
  • If a path parameter includes a wildcard (for example, generic_welcome*), the path parameter without the wildcard is used as the key.
  • You can include a context variable as a path segment in the URL property of an HTTP back end definition, but not as a query parameter. For example:

    • You can use the request.query[state] context variable as a path segment in the URL property, as shown in the following valid HTTP back end definition:

            {
              "path": "/weather/{region}",
              "methods": ["GET"],
              "backend": {
                "type": "HTTP_BACKEND",
                "url": "https://api.weather.gov/${request.path[region]}/${request.query[state]}"
              }
            }
    • You cannot use the request.query[state] context variable as a query parameter in the URL property, as shown in the following invalid HTTP back end definition:

            {
              "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).

Examples

The examples in this section assume the following API deployment definition and basic API deployment specification in a JSON file:

{
  "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": {}
}

Note the examples also apply when you're defining an API deployment specification using dialogs in the Console.

Example 1: Query path parameter in a definition

You can define a path parameter in the API deployment specification, and then use it elsewhere in the API deployment specification as a context variable.

This example creates a path parameter, region, and uses it in a context variable request.path[region] in the HTTP back end definition.

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

In this example, a request like https://<gateway-hostname>/marketing/weather/west resolves to https://api.weather.gov/west.

Example 2: Different types of context variable in the same definition

You can include different types of context variable in the same definition in the API deployment specification.

This example uses the following in the HTTP back end definition:

  • a path parameter context variable, request.path[region]
  • a query parameter context variable, request.query[state]
      {
        "path": "/weather/{region}",
        "methods": ["GET"],
        "backend": {
          "type": "HTTP_BACKEND",
          "url": "https://api.weather.gov/${request.path[region]}/${request.query[state]}"
        }
      }

In this example, a request like https://<gateway-hostname>/marketing/weather/west?state=california resolves to https://api.weather.gov/west/california.

Example 3: Multiple context variables of the same type in the same definition

You can include the same type of context variable multiple times in the same definition.

This example uses the following in the HTTP back end definition:

  • a path parameter context variable, request.path[region]
  • two query parameter context variables, request.query[state] and 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]}"
        }
      }

In this example, a request like https://<gateway-hostname>/marketing/weather/west?state=california&city=fremont resolves to https://api.weather.gov/west/california/fremont.

Example 4: Multiple values for the same parameter

It is often valid for an HTTP request to include the same query parameter multiple times. The API Gateway service saves the value of each parameter with the same name to the same record in the context table. However, in the API deployment specification, it's typically the case that only a single value can be substituted for a context variable. In these situations, you can indicate that only the first value recorded in the context table for a key is substituted in place of a context variable by enclosing the context variable within ${...}.

For example, a valid request like "https://<gateway-hostname>/marketing/weather/west?state=california&city=fremont&city=belmont" has two occurrences of the city query parameter. On receipt of the HTTP request, the API Gateway service writes both values of the city query parameter (fremont and belmont) to the same record in the request.query table. When the definition of an HTTP back end includes ${request.query[city]}, only the first value in the record is substituted in place of the context variable.

This example uses the following in the HTTP back end definition:

  • a path parameter context variable, request.path[region]
  • two query parameter context variables, request.query[state] and 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]}"
        }
      }

In this example, a request like https://<gateway-hostname>/marketing/weather/west?state=california&city=fremont&city=belmont resolves to https://api.weather.gov/west/california/fremont. Note that only fremont (as the first value in the request.query context table record identified by the city key) is substituted for the request.query[city] context variable.

Example 5: Parameter value includes encoded special characters

If an HTTP request includes special characters (for example, the character é, the space character) that have been encoded, the value is stored in the context table in its encoded form. When the value from the context table is substituted for a context variable, the encoding is preserved.

This example uses the following in the HTTP back end definition:

  • a path parameter context variable, request.path[region]
  • a query parameter context variable, 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]}"
        }
      }

In this example, a request like https://<gateway-hostname>/marketing/weather/west?city=San+Jos&#233; resolves to https://api.weather.gov/west/california/San+Jos&#233;.

Example 6: Header parameters in a definition

You can include values passed in the headers of a request as context variables in a definition. If the request includes a header, the value of the header is stored in the request.headers table, and the name of the header is used as the key.

This example uses the following in the HTTP back end definition:

  • a path parameter context variable, request.path[region]
  • a header parameter context variable, 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]}"
        }
      }

In this example, a request like https://<gateway-hostname>/marketing/weather/west included an X-Api-Key header with the value abc123def456fhi789. The request resolves to https://api.weather.gov/west/abc123def456fhi789.

Example 7: Authentication parameters in a definition

You can include values returned from an authorizer function or contained in a JWT token as context variables in a definition:

  • An authorizer function validates the token passed by an API client when calling the API Gateway service. The authorizer function returns a response that includes information such as the validity of the authorization, information about the end user, access scope, and a number of claims in key-value pairs. Depending on the authorization token, the information might be contained within the token, or the authorizer function might invoke end-points provided by the authorization server to validate the token and to retrieve information about the end user. When the API Gateway service receives a key-value pair from the authorizer function, it saves the key-value pair in the request.auth table as an authentication parameter.
  • A JWT token can optionally include a custom claim named scope, comprising a key-value pair. When the JWT token has been validated, the API Gateway service saves the key-value pair in the request.auth table as an authentication parameter.

    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.

This example uses the key-value pair returned by an authorizer function as the authentication parameter context variable request.auth[region] in the HTTP back end definition.

  {
    "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" ]
          }
        }
      }
    ]
  }

Assume an authorizer function ocid1.fnfunc.oc1.phx.aaaaaaaaac2______kg6fq validates the token passed by an API client in a call to the API Gateway service. The authorizer function returns a response to the API Gateway service that includes the region associated with the end user as a key-value pair, and also the authenticated end user's access scope. When the API Gateway service receives the key-value pair, it saves the key-value pair in the request.auth table as an authentication parameter.

In this example, a request like https://<gateway-hostname>/marketing/weather is made by an end user jdoe using an API client. The authorizer function validates the token passed by the API client in the request, and also determines that jdoe has the "weatherwatcher" access scope. The authorizer function identifies that jdoe is associated with the west region. The authorizer function returns jdoe's access scope to the API Gateway service, along with the region associated with jdoe. The API Gateway service saves the region associated with jdoe as an authentication parameter. The HTTP back end definition specifies that end users with the "weatherwatcher" access scope are allowed to access the HTTP back end. The API Gateway service uses the value of the authentication parameter context variable request.auth[region] in the request. The request resolves to 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.

This example uses the following in the HTTP back end definition:

  • the certificate context variable, 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.