Adicionando Variáveis de Contexto a Políticas e Definições de Back-End de HTTP

Descubra como usar parâmetros em chamadas de API usando variáveis de contexto do serviço API Gateway.

Chamadas para APIs implantadas em um gateway de API geralmente incluem parâmetros que você vai querer usar ao definir o seguinte nas especificações de implantação de API:

  • políticas de solicitação e políticas de resposta
  • back-ends de HTTP e HTTPS

Para permitir que você use parâmetros incluídos nas chamadas de API, o serviço API Gateway salva os valores dos seguintes tipos de parâmetro em 'tabelas de contexto' temporárias:

Cada registro em uma tabela de contexto é identificado por uma chave exclusiva.

Ao definir políticas de solicitação e resposta e back-ends de HTTP e HTTPS, você pode referenciar o valor de um parâmetro em uma tabela de contexto usando uma 'variável de contexto'. Uma variável de contexto tem o formato <context-table-name>[<key>], em que:

  • <context-table-name> é um dos seguintes: request.path, request.query, request.headers, request.auth, request.cert ou request.host
  • <key> é um dentre:
    • um nome de parâmetro de caminho definido na especificação de implantação de API
    • um nome de parâmetro de consulta incluído na solicitação à API
    • um nome de cabeçalho incluído na solicitação à API
    • um nome de parâmetro de autenticação retornado por uma função do autorizador ou contido em um token JWT
    • o nome [client_base64], representando um certificado validado com sucesso, codificado em Base64, apresentado por um cliente de API durante um handshake mTLS
    • a parte final do nome do host a ser ignorada (ao capturar a parte principal do nome do host para a qual a solicitação original foi enviada)
    • o nome de um host para o qual a solicitação foi enviada (extraído do campo de cabeçalho Host na solicitação)

Se você quiser incluir a variável de contexto em uma string na especificação de implantação de API (por exemplo, na propriedade de url de uma definição de back-end de HTTP), use o formato ${<context-table-name>[<key>]}.

Por exemplo, a variável de contexto request.path[region] no exemplo a seguir retorna o valor do registro identificado pela chave region na tabela de contexto request.path.

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

Observe o seguinte:

  • Um único registro é criado na tabela de contexto para cada parâmetro discreto em uma solicitação HTTP. Se a solicitação HTTP incluir dois (ou mais) parâmetros do mesmo tipo e com o mesmo nome, o valor de cada parâmetro com esse nome será salvo no mesmo registro na tabela de contexto e identificado pela mesma chave. No entanto, somente o primeiro valor no registro da tabela de contexto pode ser substituído no lugar de uma variável de contexto. Ao adicionar uma variável de contexto para a qual vários valores podem existir no registro da tabela de contexto e você deseja que o primeiro valor no registro da tabela de contexto seja substituído no lugar da variável de contexto, adicione a variável de contexto à especificação de implantação de API no formato ${<context-table-name>[<key>]}
  • Se um valor de parâmetro incluir caracteres especiais que foram codificados, a codificação será preservada quando o valor for salvo na tabela de contexto. Quando o valor for o substituto de uma variável de contexto, o valor codificado será substituído no lugar da variável de contexto. Por exemplo, se San José estiver incluído em um parâmetro de consulta como San+Jos&#233;, a versão codificada é a que será substituída no lugar da variável de contexto para esse parâmetro de consulta.
  • Se uma chave de variável de contexto não existir na tabela de contexto especificada, uma string vazia será substituída no lugar da variável de contexto.
  • Se uma chave de variável de contexto contiver um ponto, o ponto será tratado como qualquer outro caractere. Ele não é tratado como um indicador de uma relação pai-filho entre as strings de qualquer lado dela.
  • Se um parâmetro de caminho incluir um curinga (por exemplo, generic_welcome*), o parâmetro de caminho sem o curinga será usado como a chave.
  • Você pode incluir uma variável de contexto como um segmento de caminho na propriedade URL de uma definição de backend HTTP, mas não como um parâmetro de consulta. Por exemplo:

    • Você pode usar a variável de contexto request.query[state] como um segmento de caminho na propriedade URL, conforme mostrado na seguinte definição de backend HTTP válida:

            {
              "path": "/weather/{region}",
              "methods": ["GET"],
              "backend": {
                "type": "HTTP_BACKEND",
                "url": "https://api.weather.gov/${request.path[region]}/${request.query[state]}"
              }
            }
    • Você não pode usar a variável de contexto request.query[state] como parâmetro de consulta na propriedade URL, conforme mostrado na seguinte definição de backend HTTP inválida:

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

    Se você quiser informar uma variável de contexto como um parâmetro de consulta, use uma política de solicitação de transformação de parâmetro de consulta em vez de incluir a variável de contexto como um parâmetro de consulta na propriedade URL (consulte Adicionando Políticas de Solicitação de Transformação de Parâmetro de Consulta).

Exemplos

Os exemplos nesta seção pressupõem a seguinte definição de implantação de API e a especificação básica de implantação de API em um arquivo JSON:

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

Observe que os exemplos também se aplicam quando você está definindo uma especificação de implantação de API usando caixas de diálogo na Console.

Exemplo 1: Parâmetro do caminho de consulta em uma definição

Você pode definir um parâmetro de caminho na especificação de implantação de API e, em seguida, usá-lo em outro lugar na especificação de implantação de API como uma variável de contexto.

Este exemplo cria um parâmetro de caminho, region, e o utiliza em uma variável de contexto request.path[region] na definição de back-end de HTTP.

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

Neste exemplo, uma solicitação como https://<gateway-hostname>/marketing/weather/west é resolvida para https://api.weather.gov/west.

Exemplo 2: Diferentes tipos de variável de contexto na mesma definição

Você pode incluir diferentes tipos de variável de contexto na mesma definição na especificação de implantação de API.

Este exemplo usa o seguinte na definição de back-end de HTTP:

  • uma variável de contexto do parâmetro de caminho, request.path[region]
  • uma variável de contexto do parâmetro de consulta, request.query[state]
      {
        "path": "/weather/{region}",
        "methods": ["GET"],
        "backend": {
          "type": "HTTP_BACKEND",
          "url": "https://api.weather.gov/${request.path[region]}/${request.query[state]}"
        }
      }

Neste exemplo, uma solicitação como https://<gateway-hostname>/marketing/weather/west?state=california é resolvida para https://api.weather.gov/west/california.

Exemplo 3: Diversas variáveis de contexto do mesmo tipo na mesma definição

Você pode incluir o mesmo tipo de variável de contexto várias vezes na mesma definição.

Este exemplo usa o seguinte na definição de back-end de HTTP:

  • uma variável de contexto do parâmetro de caminho, request.path[region]
  • duas variáveis de contexto do parâmetro de consulta, request.query[state] e 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]}"
        }
      }

Neste exemplo, uma solicitação como https://<gateway-hostname>/marketing/weather/west?state=california&city=fremont é resolvida para https://api.weather.gov/west/california/fremont.

Exemplo 4: Vários valores para o mesmo parâmetro

Geralmente é válido para uma solicitação HTTP incluir o mesmo parâmetro de consulta várias vezes. O serviço API Gateway salva o valor de cada parâmetro com o mesmo nome no mesmo registro na tabela de contexto. No entanto, na especificação de implantação de API, em geral o que acontece é que apenas um único valor pode ser substituído por uma variável de contexto. Nessas situações, você pode indicar que somente o primeiro valor registrado na tabela de contexto para uma chave será substituído no lugar de uma variável de contexto, colocando a variável de contexto dentro de ${...}.

Por exemplo, uma solicitação válida como "https://<gateway-hostname>/marketing/weather/west?state=california&city=fremont&city=belmont" possui duas ocorrências do parâmetro de consulta city. Após o recebimento da solicitação HTTP, o serviço API Gateway grava os dois valores do parâmetro de consulta city (fremont e belmont) no mesmo registro na tabela request.query. Quando a definição de um back-end de HTTP inclui ${request.query[city]}, somente o primeiro valor no registro é substituído no lugar da variável de contexto.

Este exemplo usa o seguinte na definição de back-end de HTTP:

  • uma variável de contexto do parâmetro de caminho, request.path[region]
  • duas variáveis de contexto do parâmetro de consulta, request.query[state] e 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]}"
        }
      }

Neste exemplo, uma solicitação como https://<gateway-hostname>/marketing/weather/west?state=california&city=fremont&city=belmont é resolvida para https://api.weather.gov/west/california/fremont. Observe que somente fremont (como o primeiro valor no registro da tabela de contexto request.query identificado pela chave city) é o substituto da variável de contexto request.query[city].

Exemplo 5: O valor do parâmetro inclui caracteres especiais codificados

Se uma solicitação HTTP incluir caracteres especiais (por exemplo, o caractere é, o caractere de espaço) que foram codificados, o valor será armazenado na tabela de contexto em seu formato codificado. Quando o valor da tabela de contexto é colocado no lugar de uma variável de contexto, a codificação é preservada.

Este exemplo usa o seguinte na definição de back-end de HTTP:

  • uma variável de contexto do parâmetro de caminho, request.path[region]
  • uma variável de contexto do parâmetro de consulta, 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]}"
        }
      }

Neste exemplo, uma solicitação como https://<gateway-hostname>/marketing/weather/west?city=San+Jos&#233; é resolvida para https://api.weather.gov/west/california/San+Jos&#233;.

Exemplo 6: Parâmetros de cabeçalho em uma definição

Você pode incluir valores especificados nos cabeçalhos de uma solicitação como variáveis de contexto em uma definição. Se a solicitação incluir um cabeçalho, o valor do cabeçalho será armazenado na tabela request.headers e o nome do cabeçalho será usado como a chave.

Este exemplo usa o seguinte na definição de back-end de HTTP:

  • uma variável de contexto do parâmetro de caminho, request.path[region]
  • uma variável de contexto do parâmetro de cabeçalho, 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]}"
        }
      }

Neste exemplo, uma solicitação como https://<gateway-hostname>/marketing/weather/west incluiu um cabeçalho X-Api-Key com o valor abc123def456fhi789. A solicitação é resolvida como https://api.weather.gov/west/abc123def456fhi789.

Exemplo 7: Parâmetros de autenticação em uma definição

Você pode incluir valores retornados de uma função do autorizador ou contidos em um token JWT como variáveis de contexto em uma definição:

  • Uma função de autorizador valida o token passado por um cliente de API ao chamar o serviço API Gateway. A função de autorizador retorna uma resposta que inclui informações como a validade da autorização, informações sobre o usuário final, escopo de acesso e várias reivindicações em pares chave-valor. Dependendo do token de autorização, as informações podem estar contidas no token, ou a função de autorizador pode chamar pontos finais fornecidos pelo servidor de autorização para validar o token e recuperar informações sobre o usuário final. Quando o serviço API Gateway recebe um par chave-valor da função de autorizador, ele salva o par chave-valor na tabela request.auth como um parâmetro de autenticação.
  • Opcionalmente, um token JWT pode incluir uma reivindicação personalizada chamada scope, que compreende um par chave-valor. Quando o token JWT for validado, o serviço API Gateway salvará o par chave-valor na tabela request.auth como um parâmetro de autenticação.

    No caso do fluxo de autorização do OpenID Connect, dois tokens chamados id_token (sempre codificados por JWT) e access_token (podem ser codificados por JWT) são retornados. O serviço API Gateway salva os valores de token nas variáveis de contexto request.auth[id_token] e request.auth[access_token], juntamente com reivindicações personalizadas nas variáveis de contexto request.auth[id_token_claims][<claim-name>] e request.auth[access_token_claims][<claim-name>], respectivamente.

Este exemplo usa o par chave-valor retornado por uma função de autorizador como a variável de contexto do parâmetro de autenticação request.auth[region] na definição de backend HTTP.

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

Suponha que uma função de autorizador ocid1.fnfunc.oc1.phx.aaaaaaaaac2______kg6fq valide o token passado por um cliente de API em uma chamada para o serviço API Gateway. A função de autorizador retorna uma resposta ao serviço API Gateway que inclui a região associada ao usuário final como um par chave-valor e também o escopo de acesso do usuário final autenticado. Quando o serviço API Gateway recebe o par chave-valor, ele salva o par chave-valor na tabela request.auth como um parâmetro de autenticação.

Neste exemplo, uma solicitação como https://<gateway-hostname>/marketing/weather é feita por um usuário final jdoe usando um cliente de API. A função de autorizador valida o token transmitido pelo cliente da API na solicitação e também determina que jdoe tem o escopo de acesso "weatherwatcher". A função de autorizador identifica que jdoe está associado à região oeste. A função de autorizador retorna o escopo de acesso de jdoe ao serviço API Gateway, juntamente com a região associada a jdoe. O serviço API Gateway salva a região associada ao jdoe como um parâmetro de autenticação. A definição de backend HTTP especifica que os usuários finais com o escopo de acesso "weatherwatcher" podem acessar o backend HTTP. O serviço API Gateway usa o valor da variável de contexto do parâmetro de autenticação request.auth[region] na solicitação. A solicitação é resolvida como https://api.weather.gov/west.

Exemplo 8: parâmetro de certificado TLS em uma definição

Você pode incluir uma versão codificada em Base64 do certificado TLS apresentado por um cliente de API durante um handshake mTLS como uma variável de contexto em uma definição. A versão codificada em Base64 do certificado TLS é armazenada na tabela request.cert, com o nome client_base64 usado como a chave. Consulte Adicionando suporte mTLS a Implantações de API.

Este exemplo usa o seguinte na definição de back-end de HTTP:

  • a variável de contexto do certificado, 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]}"]
                }
              ]
            }
          }
        }
      }
    ]
  }

Neste exemplo, um cabeçalho chamado certificate-header é adicionado à solicitação e recebe o valor da versão codificada em Base64 do certificado TLS apresentado pelo cliente da API durante o handshake mTLS com o gateway de API.