Esta página se aplica à Apigee e à Apigee híbrida.
Confira a documentação da Apigee Edge.
Instruções condicionais são uma estrutura de controle comum em todas as linguagens de programação. Como uma linguagem de programação, a configuração de proxy da API aceita instruções condicionais para fluxos, políticas, etapas e RouteRules. Ao definir instruções condicionais, você define o comportamento dinâmico da sua API. Esse comportamento dinâmico permite executar ações como converter XML em JSON apenas para dispositivos móveis ou rotear para um URL de back-end com base no tipo de conteúdo ou verbo HTTP da mensagem de solicitação.
Este tópico mostra como usar condições para aplicar dinamicamente os recursos de gerenciamento de API no ambiente de execução, sem escrever código.
Configurar instruções condicionais
O comportamento condicional é implementado em proxies da API por meio de uma combinação de condições e variáveis. Uma instrução condicional é criada usando um elemento Condition. Veja a seguir uma condição vazia:
<Condition></Condition>
Para criar uma instrução condicional, adicione um operador condicional e uma variável usando a seguinte sintaxe:
<Condition>VARIABLE_NAME OPERATOR "VALUE"</Condition>
Exemplo:
<Condition>request.verb = "GET"</Condition>
Os operadores condicionais compatíveis incluem =
(igual a), !=
(não igual)
e >
(maior que). Para facilitar a leitura, você também pode escrever as condicionais como
texto: equals
, notequals
, greaterthan
.
Ao trabalhar com caminhos de URI, você pode usar ~/
ou MatchesPath
. Também é
possível corresponder expressões regulares JavaRegex com o operador ~~
.
As condições são usadas para definir os fluxos condicionais do proxy da API para recursos da API do back-end, descritos em Criar fluxos condicionais para recursos da API de back-end. Para ver uma lista completa de condicionais, consulte Referência de condições.
Variáveis
As condições funcionam com a avaliação dos valores de variáveis. Uma variável é uma propriedade de uma transação HTTP executada por um proxy de API ou uma propriedade de configuração de proxy da própria API. Sempre que um proxy de API recebe uma solicitação de um app, a Apigee preenche uma longa lista de variáveis associadas a itens como tempo do sistema, informações de rede do aplicativo, cabeçalhos HTTP em mensagens, configuração do proxy da API, execuções de política e assim por diante. Isso cria um contexto avançado que pode ser usado para configurar instruções condicionais.
As variáveis sempre usam uma notação pontilhada. Por exemplo, os cabeçalhos HTTP na mensagem de solicitação estão
disponíveis como variáveis chamadas request.header.HEADER_NAME
. Portanto, para avaliar Content-type header
,
use a variável request.header.Content-type
. Por
exemplo, request.header.Content-type = "application/json"
indica que o tipo de conteúdo
da solicitação precisa ser JSON.
Imagine que você precisa criar uma instrução condicional que fará com que uma política seja
aplicada somente quando uma mensagem de solicitação for GET
. Para criar uma condição que avalie o verbo HTTP
de uma solicitação, crie a instrução condicional abaixo. A variável nessa condição é
request.verb
. O valor da variável é GET
. O operador é
=
.
<Condition>request.verb = "GET"</Condition>
Também é possível usar o seguinte:
<Condition>request.verb equals "GET"</Condition>
A Apigee usa uma instrução como essa para avaliar condições. O exemplo acima será avaliado como verdadeiro se o
verbo HTTP associado à solicitação for GET
Se o verbo HTTP associado à solicitação for
POST
, a instrução será avaliada como falsa.
Para ativar o comportamento dinâmico, você pode anexar condições a fluxos, etapas e RouteRules.
Ao anexar uma condição a um fluxo, você cria um fluxo condicional. Os fluxos condicionais são executados apenas quando a condição é avaliada como verdadeira. É possível anexar quantas políticas você quiser a um fluxo condicional. Um fluxo condicional permite criar regras de processamento altamente especializadas para mensagens de solicitação ou resposta que atendam a determinados critérios.
Por exemplo, para criar um fluxo que é executado somente quando o verbo da solicitação é um GET
:
<Flows> <Flow name="ExecuteForGETs"> <Condition>request.verb="GET"</Condition> </Flow> </Flows>
Para criar um fluxo para solicitações GET
e outro para solicitações
POST
, faça o seguinte:
<Flows> <Flow name="ExecuteForGETs"> <Condition>request.verb="GET"</Condition> </Flow> <Flow name="ExecuteForPOSTs"> <Condition>request.verb="POST"</Condition> </Flow> </Flows>
Como mostrado no exemplo abaixo, você pode aplicar a condição à própria etapa da política. A
condição a seguir faz com que a política VerifyApiKey seja aplicada somente se uma mensagem de solicitação for um
POST
.
<PreFlow name="PreFlow"> <Request> <Step> <Condition>request.verb equals "POST"</Condition> <Name>VerifyApiKey</Name> </Step> </Request> </PreFlow>
Depois de definir esses fluxos condicionais, é possível anexar políticas a eles, permitindo que um proxy da API
aplique um conjunto de políticas às solicitações GET
e outro conjunto de políticas para solicitações
POST
.
Para informações de referência abrangentes, consulte os seguintes recursos:
Exemplo 1
O exemplo a seguir mostra um único fluxo condicional chamado Convert-for-devices
,
configurado no fluxo de resposta de ProxyEndpoint. Adicione a condição como um elemento à entidade
a que a condição se aplica. Neste exemplo, a condição é um componente do fluxo.
Portanto, o fluxo será executado sempre que a instrução for avaliada como true
.
<Flows> <Flow name="Convert-for-devices"> <Condition>(request.header.User-Agent = "Mozilla")</Condition> <Response> <Step><Name>ConvertToJSON</Name></Step> </Response> </Flow> </Flows>
Para cada solicitação recebida de um aplicativo, a Apigee armazena os valores de todos os cabeçalhos
HTTP presentes como
variáveis. Se a solicitação contiver um cabeçalho HTTP chamado User-Agent
, esse cabeçalho e
seu valor serão armazenados como uma variável chamada request.header.User-Agent
.
Com a configuração ProxyEndpoint acima, a Apigee verifica o valor da variável
request.header.User-Agent
para ver se a condição é avaliada como
verdadeira.
Se a condição for avaliada para true
, ou seja, o valor da variável
request.header.User-Agent
é igual aMozilla
, o fluxo condicional será
executado, e oPolítica XMLtoJSON chamadoConvertToJSON
é aplicada. Caso contrário, o fluxo
não será executado, e a resposta XML será retornada não modificada (no formato XML) para o app
solicitante.
Exemplo 2
Vamos usar um exemplo específico em que você precisa transformar a mensagem de resposta em XML para JSON, mas apenas em dispositivos móveis. Primeiro, crie a política que converterá a resposta formatada em XML da API Weather em JSON:
<XMLToJSON name="ConvertToJSON"> <Options> </Options> <OutputVariable>response</OutputVariable> <Source>response</Source> </XMLToJSON>
A configuração da política acima instrui o proxy da API a receber a mensagem da resposta, executar uma
conversão de XML para JSON com as configurações padrão e, em seguida, gravar o resultado na nova mensagem de
resposta. Se você estiver convertendo uma mensagem de request de XML em JSON, basta definir ambos
os valores como request
.
Como você quer converter respostas de XML em JSON, é necessário configurar um fluxo de resposta condicional para realizar a conversão. Por exemplo, para converter todas as respostas de XML para JSON antes de serem retornadas para o app cliente, configure o fluxo de resposta ProxyEndpoint a seguir.
<Flows> <Flow name="Convert-for-devices"> <Response> <Step><Name>ConvertToJSON</Name></Step> </Response> </Flow> </Flows>
Quando você invoca a API usando a solicitação padrão, a resposta é formatada em JSON.
No entanto, sua meta é converter apenas Relatórios meteorológicos em JSON quando o cliente solicitante for um dispositivo móvel. Para ativar esse comportamento dinâmico, você precisa adicionar uma instrução condicional ao fluxo.
Testar o fluxo condicional
Nesta solicitação de amostra, o cabeçalho HTTP User-Agent
está definido como
Mozilla
, fazendo com que a instrução condicional seja avaliada como verdadeira e o fluxo
condicional Convert-for-devices
seja executado.
curl -H "User-Agent:Mozilla" http://example.com/weather/forecastrss?w=12797282
ou para imprimir onde o Python está disponível:
curl -H "User-Agent:Mozilla" http://example.com/weather/forecastrss?w=12797282 | python -mjson.tool
Exemplo de resposta:
. . . "yweather_forecast": [ { "code": "11", "date": "12 Dec 2012", "day": "Wed", "high": "55", "low": "36", "text": "Showers" }, { "code": "32", "date": "13 Dec 2012", "day": "Thu", "high": "56", "low": "38", "text": "Sunny" } ] } . . .
Uma solicitação enviada sem o cabeçalho User-Agent
ou com um valor diferente de
Mozilla
resultará em uma resposta formatada em XML.
$ curl http://example.com/weather/forecastrss?w=12797282
A resposta XML não modificada é retornada.
Exemplo de resposta:
<yweather:forecast day="Wed" date="12 Dec 2012" low="36" high="55" text="Showers" code="11" /> <yweather:forecast day="Thu" date="13 Dec 2012" low="38" high="56" text="Sunny" code="32" />
Correspondência de padrões
Nesta seção, descrevemos como usar a correspondência de padrões com condições em um fluxo da Apigee.
Operadores
Nesta seção, descrevemos como usar os seguintes operadores de correspondência de padrão em instruções condicionais:
- Operador
Matches
: correspondência de padrões simples - Operador JavaRegex: controle de filtros sobre a correspondência
- Operador
MatchesPath
: correspondência de fragmentos de caminho
Correspondências
Vejamos primeiro o operador condicional Matches
ou ~
. Esses dois operadores são os mesmos. A versão em inglês, Matches
, é considerada uma opção mais legível.
Resumo: o operador Matches
oferece duas possibilidades. Corresponda literalmente à string ou faça uma correspondência curinga com *
. Como o esperado, o caractere curinga corresponde a zero ou mais caracteres. Vamos ver como isso funciona.
O XML a seguir mostra uma condição "Step". Ele executa a política SomePolicy quando a condição é
avaliada como verdadeira. Neste exemplo, testamos a variável proxy.pathsuffix
, uma
variável integrada na Apigee que armazena o sufixo do caminho da solicitação. No entanto, é possível testar
o valor de qualquer variável de fluxo que contenha uma string. Nesse caso, se o caminho base da
solicitação de entrada for /animals
e a solicitação for /animals/cat
, o
sufixo do caminho será a string literal /cat
.
<PreFlow name="PreFlow"> <Request> <Step> <Condition>(proxy.pathsuffix Matches "/cat")</Condition> <Name>SomePolicy</Name> </Step> </Request> <Response/> </PreFlow>
Pergunta: Qual sufixo do caminho do proxy fará com que SomePolicy seja executada? Só há uma possibilidade.
Chamada de API:
GET http://example.com/matchtest/cat
A política é executada? Sim, porque o sufixo do caminho do proxy corresponde exatamente a
/cat
. Ela não será executada se o sufixo for /bat
, /dog
, /
ou
qualquer outra coisa.
Agora, considere esta instrução condicional em que usamos o caractere curinga
*
:
<Condition>(proxy.pathsuffix Matches "/*at")</Condition>
Chamada de API:
GET http://example.com/matchtest/cat
A política é executada? Sim, porque o caractere curinga corresponde a qualquer caractere, e
"/cat
é uma correspondência.
Chamada de API:
GET http://example.com/matchtest/bat
A política é executada? Sim, porque o caractere curinga corresponde a qualquer caractere, "/bat"
é uma correspondência.
Chamada de API:
GET http://example.com/matchtest/owl
A política é executada? Certamente não, embora o caractere curinga corresponda a o
,
as letras wl
não são correspondidas.
Agora, vamos mover o caractere curinga ao final do sufixo:
<Condition>(proxy.pathsuffix Matches "/cat*")</Condition>
Chamada de API:
GET http://example.com/matchtest/cat
A política é executada? Sim, porque o caractere curinga corresponde a zero ou mais dos caracteres.
Chamada de API:
GET http://example.com/matchtest/bat
A política é executada? Não, /bat
não é uma correspondência.
Chamada de API:
GET http://example.com/matchtest/cat123
A política é executada? Sim, o caractere curinga corresponde a zero ou mais dos caracteres, portanto,
123
produz uma correspondência.
Chamada de API:
GET http://example.com/matchtest/cat/bird/mouse
A política é executada? Sim, porque o caractere curinga corresponde a zero ou mais dos caracteres, de modo que
/bird/mouse
produz uma correspondência. Observe como uma expressão como essa pode causar
problemas, porque ela corresponde a tudo depois dos caracteres literais.
Pergunta: o operador Matches
diferencia maiúsculas de minúsculas?
Sim. Vamos supor que você tenha uma condição como esta:
<Condition>(proxy.pathsuffix Matches "/*At")</Condition>
Chamada de API:
GET http://example.com/matchtest/cat
A política é executada? Não, o caractere curinga corresponde a qualquer letra (independentemente do caso), mas o
a
minúsculo não corresponde a A
.
Chamada de API:
GET http://example.com/matchtest/bAt
A política é executada? Sim, o caso corresponde.
Pergunta: como posso fazer o escape de caracteres com o operador Matches
Use o caractere de porcentagem %
para evitar caracteres reservados. Exemplo:
<Condition>(proxy.pathsuffix Matches "/c%*at")</Condition>
Chamada de API:
GET http://example.com/matchtest/cat
A política é executada? Não, o operador Matches
está procurando a string literal
c*at
.
Chamada de API:
GET http://example.com/matchtest/c*at
Pergunta:a política é executada?
Sim, com este caminho, embora seja um pouco incomum.
JavaRegex
O operador Matches
é ótimo para situações simples. Mas é possível usar outro operador,
como JavaRegex ou ~~
. Esses dois são o mesmo operador, mas o JavaRegex é
considerado mais legível. Ela é chamada de JavaRegex porque permite a correspondência de padrões
de expressão regular, e a Apigee segue as mesmas regras que as classes do
pacote
java.util.regex na linguagem Java. O funcionamento do operador JavaRegex é muito diferente do operador
Matches
. Portanto, é importante não confundir os dois.
Resumo: o operador JavaRegex permite usar a sintaxe de expressão regular em declarações condicionais.
O código a seguir mostra uma condição "Step". Ele executará a política SomePolicy se a condição for avaliada
como true
. Neste exemplo, testamos a variável proxy.pathsuffix
,
uma variável integrada na Apigee que armazena o sufixo do caminho da solicitação. Se o caminho base da solicitação de
entrada for /animals
e a solicitação for /animals/cat
, o sufixo
do caminho será a string literal /cat
.
<PreFlow name="PreFlow"> <Request> <Step> <Condition>(proxy.pathsuffix JavaRegex "/cat")</Condition> <Name>SomePolicy</Name> </Step> </Request> <Response/> </PreFlow>
Pergunta: Qual sufixo do caminho do proxy fará com que SomePolicy seja executada? Assim como
com o operador Matches
, há apenas uma possibilidade nesse caso.
Chamada de API:
GET http://example.com/matchtest/cat
A política é executada? Sim, porque o sufixo do caminho do proxy corresponde exatamente a
/cat
. Ela não será executada se o sufixo for /bat
ou /dog
ou qualquer outra
coisa.
Agora, vamos criar uma expressão regular usando o quantificador *
. Esse quantificador corresponde a zero
ou mais dos caracteres anteriores.
<Condition>(proxy.pathsuffix JavaRegex "/c*t")</Condition>
Chamada de API:
GET http://example.com/matchtest/cat
A política é executada? Não. O quantificador *
corresponde ao
caractere anterior, que é umc
.
Chamada de API:
GET http://example.com/matchtest/ccccct
A política é executada? Sim, porque o caractere curinga corresponde a zero ou mais do caractere anterior.
Em seguida, usamos o quantificador ?
, que corresponde ao caractere anterior uma vez ou
nenhum.
<Condition>(proxy.pathsuffix JavaRegex "/ca?t")</Condition>
Chamada de API:
GET http://example.com/matchtest/cat
A política é executada? Sim. O quantificador ?
corresponde a zero ou uma ocorrência do caractere
anterior, que é um a
.
Chamada de API:
GET http://example.com/matchtest/ct
A política é executada? Sim. O quantificador ?
corresponde a um
ou nenhum do caractere anterior. Nesse caso, não há caractere a
. Portanto, a
condição é avaliada como true
.
Chamada de API:
GET http://example.com/matchtest/caat
A política é executada? Não. O quantificador ?
corresponde a um do caractere
anterior, que é um a
.
Em seguida, usaremos o estilo [abc]
ou agrupamento da expressão regex. Ele corresponde aos caracteres a
, b
ou c
.
<Condition>(proxy.pathsuffix JavaRegex "/[cbr]at")</Condition>
Chamada de API:
GET http://example.com/matchtest/cat
A política é executada? Sim. Aqui, estamos usando expressões regulares, e a expressão [cbr]
corresponde a c
, b
ou r
. Estas chamadas também são correspondentes:
GET http://example.com/matchtest/bat
GET http://example.com/matchtest/rat
No entanto, esta não é uma correspondência:
GET http://example.com/matchtest/mat
Pergunta: o operador JavaRegex diferencia maiúsculas de minúsculas?
Sim. Vamos supor que você tenha uma condição como esta:
<Condition>(proxy.pathsuffix JavaRegex "/ca?t")</Condition>
Chamada de API:
GET http://example.com/matchtest/cat
A política é executada? Sim, a regex corresponde a zero ou um dos caracteres anteriores, que é
a
.
Chamada de API:
GET http://example.com/matchtest/cAt
Pergunta: a política é executada?
Não, porque o A
maiúsculo não corresponde ao a
minúsculo.
MatchesPath
O operador MatchesPath
também pode ser especificado assim: ~/
. Ele é similar aos operadores Matches
(~
) e JavaRegex (~~
). No entanto, MatchesPath
é totalmente diferente.
Lembre-se de que esse operador analisa um caminho como uma série de partes. Portanto, se o caminho for:
/animals/cats/wild
, você poderá pensar no caminho como parte das partes
/animals
, /cats
e /wild
.
Com o operador MatchesPath
, é possível usar duas notações curinga: um asterisco (*) e um
asterisco duplo (**
). O único asterisco corresponde a um elemento de caminho. O asterisco duplo corresponde a
um ou vários elementos de caminho.
Vejamos um exemplo. Neste exemplo, testamos a variável proxy.pathsuffix
,
uma variável integrada na Apigee que armazena o sufixo do caminho da solicitação. No entanto, é possível
testar o valor de qualquer variável de fluxo que contenha uma string.
<PreFlow name="PreFlow"> <Request> <Step> <Condition>(proxy.pathsuffix MatchesPath "/animals/*")</Condition> <Name>SomePolicy</Name> </Step> </Request> <Response/> </PreFlow>
Pergunta: Qual sufixo do caminho do proxy fará com que SomePolicy seja executada?
Chamada de API:
GET http://example.com/matchtest/animals
Pergunta: a política é executada?
Não, porque a condição requer outro elemento de caminho após
/animals
, conforme especificado por /*
.
Chamada de API:
GET http://example.com/matchtest/animals
/
A política é executada? Sim, o caminho tem outro elemento de caminho (a parte depois de
/animals/
), mas ele está vazio.
Chamada de API:
GET http://example.com/matchtest/animals/cats
A política é executada? Sim, porque o caminho tem um elemento (/cats
)
que vem depois de /animals
.
Chamada de API:
GET http://example.com/matchtest/animals/cats/wild
Pergunta: a política é executada?
Não, porque o único asterisco corresponde apenas a um elemento de caminho, e
essa API tem mais de um elemento depois de /animals
.
Agora, vamos usar o asterisco duplo:
<PreFlow name="PreFlow"> <Request> <Step> <Condition>(proxy.pathsuffix MatchesPath "/animals/**")</Condition> <Name>SomePolicy</Name> </Step> </Request> <Response/> </PreFlow>
Pergunta: Qual sufixo do caminho do proxy fará com que SomePolicy seja executada?
Chamada de API:
GET http://example.com/matchtest/animals
A política é executada? Não, porque a condição requer pelo menos um elemento de caminho a seguir especificado
por /**
.
Chamada de API:
GET http://example.com/matchtest/animals
/
A política é executada?
Sim, o caminho tem outro elemento de caminho (a parte depois de
/animals/
), mas ele está vazio.
Chamada de API:
GET http://example.com/matchtest/animals/cats
A política é executada?
Sim, porque o caminho tem pelo menos um elemento que vem depois de
/animals
Chamada de API:
GET http://example.com/matchtest/animals/cats/wild
A política é executada?
Sim, porque o caminho tem mais de um elemento que vem após
/animals
Misturar asteriscos
É possível usar combinações dos asteriscos simples (*) e duplo (**) para refinar ainda mais sua correspondência de caminho.
<PreFlow name="PreFlow"> <Request> <Step> <Condition>(proxy.pathsuffix MatchesPath "/animals/*/wild/**")</Condition> <Name>SomePolicy</Name> </Step> </Request> <Response/> </PreFlow>
Chamada de API:
Todas essas chamadas de API produzirão uma correspondência:
GET http://example.com/matchtest/animals/cats/wild/
e
GET http://example.com/matchtest/animals/dogs/wild/austrailian
e
GET
http://example.com/matchtest/animals/birds/wild/american/finches
Recursos de API
Serviços RESTful são coleções de recursos da API. Um recurso de API é um fragmento de caminho de URI que identifica uma entidade que os desenvolvedores podem acessar chamando sua API. Por exemplo, se o serviço fornece relatórios meteorológicos e previsões do tempo, seu serviço de back-end pode definir dois recursos da API:
http://mygreatweatherforecast.com/reports
http://mygreatweatherforecast.com/forecasts
Quando você criar um proxy de API (como mostrado em Criar seu primeiro proxy de API), é necessário criar pelo menos um URL base de alias mapeado para o serviço de back-end. Exemplo:
URL base de back-end | URL de proxy de API novo/equivalente |
---|---|
http://mygreatweatherforecast.com |
http://example.com/mygreatweatherforecast |
Nesse ponto, é possível fazer chamadas de API para seu back-end usando qualquer URL de base. Mas quando você usa o URL do proxy da API, as coisas começam a ficar interessantes.
Além da análise da API que a Apigee começa a coletar quando você usa o proxy da API, os proxies
também permitem definir fluxos condicionais que mapeiam os recursos no back-end. Essencialmente, se
uma chamada GET
chega ao recurso /reports
, a Apigee precisa fazer algo.
A imagem a seguir mostra a diferença de comportamento entre dois URLs que acessam o mesmo back-end. Um é o URL do recurso sem proxy, o outro é um proxy de API da Apigee com um fluxo condicional para o mesmo recurso de back-end. Descreveremos os fluxos condicionais em mais detalhes abaixo.
Como os proxies de API são mapeados para recursos de back-end específicos
Com um URL de proxy da API mapeado para o URL base do serviço de back-end (ao criar o
proxy), é possível adicionar fluxos condicionais a recursos específicos, como os recursos /reports
e /forecasts
. mencionado anteriormente.
Digamos que você queira que a Apigee faça algo quando as chamadas chegam aos recursos
/reports
ou /forecasts
. Você não informa ao Apigee
o que fazer, apenas que ele precisa detectar chamadas para esses recursos. Faça isso
com condições. No proxy da API Apigee, é possível criar fluxos condicionais para
/reports
e /forecasts
. Para fins conceituais, o seguinte XML de proxy
da API mostra como essas condições podem aparecer.
<Flows> <Flow name="reports"> <Description/> <Request/> <Response/> <Condition>(proxy.pathsuffix MatchesPath "/reports") and (request.verb = "GET")</Condition> </Flow> <Flow name="forecasts"> <Description/> <Request/> <Response/> <Condition>(proxy.pathsuffix MatchesPath "/forecasts") and (request.verb = "GET")</Condition> </Flow> </Flows>
Essas condições dizem que Quando uma solicitação GET
vem com /reports
e
/forecasts
no URL, a Apigee faz tudo o que você (o desenvolvedor da API) informa,
por meio das políticas anexadas. para esses fluxos.
Veja um exemplo de dizer ao Apigee o que fazer quando uma condição é atendida. No XML de proxy de API a seguir,
quando uma solicitação GET
é enviada para https://example.com/mygreatweatherforecast/reports
, a Apigee executa a política
XML-to-JSON-1
na resposta.
<Flows> <Flow name="reports"> <Description/> <Request/> <Response> <Step> <Name>XML-to-JSON-1</Name> </Step> </Response> <Condition>(proxy.pathsuffix MatchesPath "/reports") and (request.verb = "GET")</Condition> </Flow>
Além desses fluxos condicionais opcionais, cada proxy de API também tem dois fluxos
padrão: um <PreFlow>
executado antes dos fluxos condicionais e um
<PostFlow>
executado depois dos fluxos condicionais. Eles são úteis para
executar políticas quando qualquer chamada é feita em um proxy de API. Por exemplo, se você quiser
verificar a chave de API de um app em todas as chamadas, independentemente do recurso de back-end que está sendo acessado,
poderá colocar uma política "Verificar chave de API" em <PreFlow>
. Para mais informações sobre fluxos, consulte
Como configurar fluxos.
Criar fluxos condicionais para recursos de back-end
A definição de fluxos condicionais para recursos de back-end em um proxy de API é completamente opcional. No entanto, esses fluxos condicionais permitem aplicar o gerenciamento e o monitoramento refinados.
Você poderá:
- aplicar o gerenciamento de modo que reflita a semântica do modelo da API;
- Aplicar políticas e comportamento scriptado a caminhos de recursos individuais (URIs)
- Coletar métricas refinadas para os serviços do Google Analytics
Por exemplo, imagine que você precisa aplicar tipos diferentes de lógica aos recursos de back-end
/developers
a /apps
.
Para fazer isso, adicione dois fluxos condicionais ao proxy da API: /developers
e
/apps
.
Novo Editor de proxy
Para adicionar um fluxo condicional, faça o seguinte:
- Selecione a guia Develop no Proxy Editor.
- Selecione Proxy endpoints > default no painel à esquerda.
- Clique no botão + acima do painel Resposta.
- Na caixa de diálogo Add consigo Flow, insira as seguintes configurações:
- Nome do fluxo:
Developers
- Tipo de condição:
Path
- Caminho:
/developers
A condição será acionada (e as políticas serão executadas) se uma chamada for enviada ao proxy com
/developers
no final do URI. - Nome do fluxo:
- Agora adicione um fluxo condicional para
/apps
e suponha que você queira que a condição seja acionada tanto no URI quanto no verboPOST
em uma solicitação. A configuração envolve a configuração do seguinte:- Nome do fluxo:
Apps
- Tipo de condição:
Path and Verb
- Caminho:
/apps
- Verbo:
POST
A condição será acionada (e as políticas serão executadas) se uma chamada for enviada ao proxy com
/apps
no final do URI e um verboPOST
. - Nome do fluxo:
Os fluxos adicionados são exibidos no painel Response:
Editor de proxy clássico
No painel Desenvolvimento do editor do proxy de API de Navegador, clique em ao lado de padrão nos Endpoints de proxy.
Na janela Novo fluxo condicional, insira as seguintes configurações de chave:
- Nome do fluxo:
Developers
- Tipo de condição:
Path
- Caminho:
/developers
A condição será acionada (e as políticas serão executadas) se uma chamada for enviada ao proxy
com /developers
no final do URI.
Agora adicione um fluxo condicional para /apps
e suponha que você queira que a condição seja acionada
tanto no URI quanto no verbo POST
em uma solicitação. A configuração envolve a configuração do
seguinte:
- Nome do fluxo:
Apps
- Tipo de condição:
Path and Verb
- Caminho:
/apps
- Verbo:
POST
A condição será acionada (e as políticas serão executadas) se uma chamada for enviada ao proxy
com /apps
no final do URI e um verbo POST
.
No painel do Navegador, você verá novos fluxos para Apps e Desenvolvedores.
Selecione um dos fluxos para ver a configuração de fluxo condicional na visualização de código do editor de proxy da API:
<Flow name="Apps"> <Description>Developer apps registered in Developer Services</Description> <Request/> <Response/> <Condition>(proxy.pathsuffix MatchesPath "/apps") and (request.verb = "POST")</Condition> </Flow>
Como você pode ver, os recursos da API são simplesmente fluxos condicionais que avaliam o caminho do URI da
solicitação de entrada. A variável proxy.pathsuffix
identifica o URI da solicitação que segue
o BasePath configurado na configuração do ProxyEndpoint.
Cada recurso de API definido é implementado por um fluxo condicional no proxy da API. Consulte Como configurar fluxos.
Depois de implantar o proxy da API no ambiente de teste, a seguinte solicitação:
http://example.com/PROXY_PATH/apps
fará com que a condição seja avaliada como true
e que esse fluxo, com todas as
políticas associadas, será executado.
O exemplo de condição a seguir usa uma expressão regular Java para reconhecer chamadas feitas para o
recurso /apps
com ou sem uma barra à direita (/apps
ou
/apps/**
):
<Condition>(proxy.pathsuffix JavaRegex "/apps(/?)") and (request.verb = "POST")</Condition>
Para saber mais sobre esse tipo de condição, consulte Como fazer a correspondência independentemente de haver um "/" antes de ... naComunidade da Apigee.
Como modelar URIs hierárquicos
Em alguns casos, você terá recursos hierárquicos da API. Por exemplo, a API Developer Apps list fornece um método para listar todos os apps que pertencem a um desenvolvedor. O caminho do URI é:
/developers/DEVELOPER_EMAIL/apps
Você pode ter recursos em que um código exclusivo é gerado para cada entidade em uma coleção, que às vezes é anotada da seguinte maneira:
/genus/:id/species
Esse caminho se aplica igualmente aos dois URIs a seguir:
/genus/18904/species /genus/17908/species
Para representar essa estrutura em um recurso de API, use caracteres curinga. Exemplo:
/developers/*/apps /developers/*example.com/apps /genus/*/species
Eles resolverão os URIs hierárquicos como recursos da API corretamente.
Em alguns casos, especialmente para APIs profundamente hierárquicas, basta resolver tudo que está abaixo de um determinado fragmento de URI. Para isso, use um caractere curinga de asterisco duplo na definição do recurso. Por exemplo, se você definir o seguinte recurso da API:
/developers/**
Esse recurso de API resolverá os seguintes caminhos de URI:
/developers/DEVELOPER_EMAIL/apps /developers/DEVELOPER_EMAIL/keys /developers/DEVELOPER_EMAIL/apps/APP_ID/keys
Veja como ficaria a condição do fluxo condicional na definição do proxy da API:
<Condition>(proxy.pathsuffix MatchesPath "/developers/**") and (request.verb = "POST")</Condition>
Mais exemplos
Condição anexada a RouteRule
<RouteRule name="default"> <!--this routing executes if the header indicates that this is an XML call. If true, the call is routed to the endpoint XMLTargetEndpoint--> <Condition>request.header.content-type = "text/xml"</Condition> <TargetEndpoint>XmlTargetEndpoint</TargetEndpoint> </RouteRule>
Condição anexada a uma política
<Step> <!--the policy MaintenancePolicy only executes if the response status code is exactly 503 --> <Condition>response.status.code = 503</Condition> <Name>MaintenancePolicy</Name> </Step>
Fluxo condicional
<!-- this entire flow is executed only if the request verb is a GET--> <Flow name="GetRequests"> <Condition>request.verb="GET"</Condition> <Request> <Step> <!-- this policy only executes if request path includes a term like statues--> <Condition>request.path ~ "/statuses/**"</Condition> <Name>StatusesRequestPolicy</Name> </Step> </Request> <Response> <Step> <!-- this condition has multiple expressions. The policy executes if the response code status is exactly 503 or 400--> <Condition>(response.status.code = 503) or (response.status.code = 400)</Condition> <Name>MaintenancePolicy</Name> </Step> </Response> </Flow>
Operadores de amostra em condições
Veja alguns exemplos de operadores usados para criar condições:
request.header.content-type = text/xml
request.header.content-length < 4096 && request.verb = PUT
response.status.code = 404 || response.status.code = 500
request.uri MatchesPath /*/statuses/**
request.queryparam.q0 NotEquals 10
Um exemplo prático: ignore
/
no final de um caminho.
Os desenvolvedores da Apigee costumam querer lidar com os seguintes sufixos de caminho: /cat
e
/cat/
. Isso ocorre porque alguns usuários ou clientes podem chamar a API com uma barra extra
no final do caminho. Você precisa ser capaz de lidar com isso nas declarações
condicionais. Esse caso de uso exato foi discutido em
Como fazer a correspondência independentemente de haver um "/ no URL...
Se preferir, você pode fazer isso sem usar o Regex da seguinte maneira:
<PreFlow name="PreFlow"> <Request> <Step> <Condition>(proxy.pathsuffix = "/cat") OR (proxy.pathsuffix = "/cat/")</Condition> <Name>SomePolicy</Name> </Step> </Request> <Response/> </PreFlow>
Essa é uma boa opção. É claro e legível.
No entanto, você pode fazer o mesmo com Regex. Os parênteses são usados para agrupar a parte do regex da instrução, mas eles não são necessários.
<Condition>(proxy.pathsuffix JavaRegex "/cat(/?)"</Condition>
Chamadas de API:
GET http://example.com/matchtest/cat
or GET http://example.com/matchtest/cat
/
A política é executada? Sim. Em uma expressão regular, o caractere ?
significa: corresponder a zero ou a um dos caracteres anteriores. Portanto,
/cat
e /cat/
são correspondências.
Chamada de API:
GET http://example.com/matchtest/cat/spotted
A política é executada? Não. A expressão regular corresponde a zero ou apenas uma ocorrência do caractere anterior, e nada mais é permitido.
Correspondência de strings arbitrárias com o JavaRegex
Em todos os exemplos deste tópico, mostramos como corresponder a uma das variáveis de fluxo integradas:
proxy.pathsuffix
. É possível fazer a correspondência de padrões em qualquer string arbitrária ou
variável de fluxo, independentemente de ser ou não uma variável de fluxo integrada, como proxy.pathsuffix
.
Por exemplo, se você tiver uma condição que testa uma string arbitrária, talvez uma string retornada
em um payload de back-end ou uma string retornada de uma pesquisa do servidor de autenticação, use
operadores correspondentes para testá-la. Se você usar JavaRegex
, a expressão regular será comparada com
a string do assunto inteiro. Se o assunto for abc
e a expressão regular for [a-z]
,
não há correspondência, porque [a-z]
corresponde exatamente a um caractere alfa. A expressão
[a-z]+
funciona, assim como [a-z]*
e [a-z]{3}
.
Vamos ver um exemplo rápido: Suponha que o servidor de autenticação retorne uma lista de papéis
como uma string delimitada por vírgulas: editor, author, guest
.
Para testar a presença do papel de editor, essa construção não funcionará, porque editor
é apenas parte de toda a string.
<Condition>returned_roles ~~ "editor"</Condition>
No entanto, essa construção funcionará:
<Condition>returned_roles ~~ ".*\beditor\b.*")</Condition>
Ela funciona porque leva em consideração quebras de palavras e quaisquer outras partes da string
.*
com o prefixo.
Neste exemplo, também é possível testar editor
com o operador Matches
:
<Condition>returned_roles ~~ "*editor*")</Condition>
No entanto, nos casos em que é necessário maior precisão, o JavaRegex geralmente é uma escolha melhor.
Como usar aspas duplas nas expressões JavaRegex
A sintaxe Condition exige que uma expressão JavaRegex esteja entre aspas duplas. Portanto, se você tiver uma expressão regex que inclua aspas duplas, precisará de uma maneira alternativa para correspondê-las. A resposta é Unicode. Por exemplo, digamos que você passe um cabeçalho que inclua aspas duplas, como:
-H 'content-type:multipart/related; type="application/xop+xml"'
Se você tentar corresponder esse cabeçalho a uma condição regex, verá um erro Invalid Condition
porque a expressão
inclui aspas duplas:
request.header.Content-Type ~~ "(multipart\/related)(; *type="application\/xop\+xml\")"
A solução é substituir as aspas duplas baseadas em ASCII pelo equivalente Unicode \u0022
. Por exemplo,
a expressão a seguir é válida e produz o resultado esperado:
request.header.Content-Type ~~ "(multipart\/related)(; *type=\u0022application\/xop\+xml\u0022)"