Esta é a documentação do Apigee Edge.
Acesse
Documentação da Apigee X. informações
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 para criar a seguinte estrutura:
<Condition>{variable.name}{operator}{"value"}</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
. Você também
pode 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, o Apigee Edge preenche um longa lista de variáveis associadas a itens como horário do sistema, tempo de rede cabeçalhos HTTP em mensagens, a configuração do proxy da API, execuções de políticas 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 o
cabeçalho do tipo de conteúdo, 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>
<Condition>request.verb equals "GET"</Condition>
O Edge usa essa instrução para avaliar as 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 GETs e outro para POSTs:
<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>
Assim que você tiver definido esses fluxos condicionais, poderá anexar políticas a eles, permitindo que um proxy de API aplique um conjunto de políticas para 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 verdadeira.
<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, o Edge 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 do ProxyEndpoint acima, o Edge verifica o valor do
request.header.User-Agent
para ver se a condição é avaliada como
verdade.
Se a condição for avaliada como verdadeira, ou seja, o valor da variável
request.header.User-Agent
for igual a Mozilla
, o fluxo condicional será
executado e a política XMLtoJSON chamada ConvertToJSON
será 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://{org_name}-test.apigee.net/weather/forecastrss?w=12797282
ou para imprimir onde o Python está disponível:
$ curl -H "User-Agent:Mozilla" http://{org_name}-test.apigee.net/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://{org_name}-test.apigee.net/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 de correspondência: correspondência de padrões simples
- Operador JavaRegex: controle de filtros sobre a correspondência
- OperadorMatchesPath: correspondência de fragmento 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 "Correspondências" oferece duas possibilidades. Corresponde literalmente à string ou faça uma correspondência curinga com "*". Como você pode esperar, 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 no Edge 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://artomatic-test.apigee.net/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://artomatic-test.apigee.net/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://artomatic-test.apigee.net/matchtest/bat
A política é executada? Sim, porque o caractere curinga corresponde a qualquer caractere, "/bat"
é uma correspondência.
Chamada de API:
GET http://artomatic-test.apigee.net/matchtest/owl
A política é executada? Claro que não, embora o caractere curinga corresponda a "o
",
as letras "wl
" não correspondem.
Agora, vamos mover o caractere curinga ao final do sufixo:
<Condition>(proxy.pathsuffix Matches "/cat*")</Condition>
Chamada de API:
GET http://artomatic-test.apigee.net/matchtest/cat
A política é executada? Sim, porque o caractere curinga corresponde a zero ou mais dos caracteres.
Chamada de API:
GET http://artomatic-test.apigee.net/matchtest/bat
A política é executada? Não, "/bat
" não é uma correspondência.
Chamada de API:
GET http://artomatic-test.apigee.net/matchtest/cat123
A política é executada? Sim, o curinga corresponde a zero ou mais caracteres, portanto
"123
" produz uma correspondência.
Chamada de API:
GET http://artomatic-test.apigee.net/matchtest/cat/bird/mouse
A política é executada? Sim, porque o curinga corresponde a zero ou mais caracteres, então
"/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 "Correspondências" 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://artomatic-test.apigee.net/matchtest/cat
A política é executada? Não, o curinga corresponde a qualquer letra (independentemente do caso), mas o "a" minúsculo não corresponde a "A".
Chamada de API:
GET http://artomatic-test.apigee.net/matchtest/bAt
A política é executada? Sim, o caso corresponde.
Pergunta: como posso fazer o escape de caracteres com o operador "Correspondências"?
Use o caractere de porcentagem "%" para escapar caracteres reservados. Exemplo:
<Condition>(proxy.pathsuffix Matches "/c%*at")</Condition>
Chamada de API:
GET http://artomatic-test.apigee.net/matchtest/cat
A política é executada? Não, o operador "Matches" está procurando a string literal. "c*at".
Chamada de API:
GET http://artomatic-test.apigee.net/matchtest/c*at
Pergunta:a política é executada?
Sim, com este caminho, embora seja um pouco incomum.
JavaRegex
Como você pode ver, o operador "Correspondências" é ótimo para situações simples. Mas é possível usar outro operador, o operador "JavaRegex" ou "~~". Esses dois são o mesmo operador, mas o JavaRegex é considerado mais legível. Ele se chama JavaRegex porque permite expressões regulares correspondência de padrões, e o Edge segue as mesmas regras das classes na classe java.util.regex package na linguagem Java. O funcionamento do operador JavaRegex é muito diferente do operador correspondente. Por isso, é importante não confundir.
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". Ela executará a política SomePolicy se a condição
avalia como verdadeiro. Neste exemplo, testamos a variável proxy.pathsuffix
, um modelo
variável no Edge 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 "Correspondências", só há uma possibilidade nesse caso.
Chamada de API:
GET http://artomatic-test.apigee.net/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 do caractere anterior.
<Condition>(proxy.pathsuffix JavaRegex "/c*t")</Condition>
Chamada de API:
GET http://artomatic-test.apigee.net/matchtest/cat
A política é executada? Não! O "*" corresponde a zero ou mais
caractere anterior, que é "c
".
Chamada de API:
GET http://artomatic-test.apigee.net/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
não está.
<Condition>(proxy.pathsuffix JavaRegex "/ca?t")</Condition>
Chamada de API:
GET http://artomatic-test.apigee.net/matchtest/cat
A política é executada? Sim. O evento "?
" corresponde a zero ou uma ocorrência de
o caractere anterior, que é "a
";
Chamada de API:
GET http://artomatic-test.apigee.net/matchtest/ct
A política é executada? Sim. O evento "?
" quantificador corresponde a um ou
nenhum do caractere anterior. Nesse caso, não existe um "a" , então o
condição é avaliada como verdadeira.
Chamada de API:
GET http://artomatic-test.apigee.net/matchtest/caat
A política é executada? Não. O "?" corresponde a um dos valores anteriores
que é um "a
".
Em seguida, usamos 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://artomatic-test.apigee.net/matchtest/cat
A política é executada? Sim. Estamos usando expressões regulares aqui, e a
"[cbr]
" corresponde a "c", "b" OR "r". Estas chamadas também são correspondentes:
GET http://artomatic-test.apigee.net/matchtest/bat
GET http://artomatic-test.apigee.net/matchtest/rat
No entanto, esta não é uma correspondência:
GET http://artomatic-test.apigee.net/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://artomatic-test.apigee.net/matchtest/cat
A política é executada? Sim, a regex corresponde a zero ou a um dos caracteres anteriores, que é "a".
Chamada de API:
GET http://artomatic-test.apigee.net/matchtest/cAt
Pergunta: a política é executada?
Não, porque a letra "A" não corresponde a "a" em letras minúsculas.
MatchesPath
O operador MatchesPath
também pode ser especificado assim: ~/". Ele é um pouco parecido com os operadores
Matches
(~) e JavaRegex (~~). Mas 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 composto pelas 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.
Vamos conferir um exemplo. Neste exemplo, testamos a variável proxy.pathsuffix
,
Uma variável integrada no Edge 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://artomatic-test.apigee.net/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://artomatic-test.apigee.net/matchtest/animals
/
A política é executada? Sim, ele tem outro elemento de caminho (a parte depois de
"/animals/
"), mas ele está vazio.
Chamada de API:
GET http://artomatic-test.apigee.net/matchtest/animals/cats
A política é executada? Sim, porque o caminho claramente tem um elemento ("/cats
")
que vem depois de "/animals
"
Chamada de API:
GET http://artomatic-test.apigee.net/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://artomatic-test.apigee.net/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://artomatic-test.apigee.net/matchtest/animals
/
A política é executada?
Sim, ele tem outro elemento de caminho (a parte depois de
"/animals/
"), mas ele está vazio.
Chamada de API:
GET http://artomatic-test.apigee.net/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://artomatic-test.apigee.net/matchtest/animals/cats/wild
A política é executada?
Sim, porque o caminho tem mais de um elemento que vem depois de
"/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://artomatic-test.apigee.net/matchtest/animals/cats/wild/
e
GET http://artomatic-test.apigee.net/matchtest/animals/dogs/wild/austrailian
e
GET
http://artomatic-test.apigee.net/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://{your_org}-{environment}.apigee.net/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 de API que o Edge começa a coletar quando você usa o proxy de API, os proxies também permitem definir fluxos condicionais associados aos recursos no back-end. Em essência, "Se quando uma chamada GET entra no recurso /reports, o Edge deve fazer alguma coisa."
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 da API Edge com uma 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 o Edge "faça algo" quando as chamadas forem recebidas
/reports
ou /forecasts
. Neste ponto, você não informa ao Edge
o que fazer, apenas que ele deve ouvir as chamadas para esses recursos. Faça isso
com condições. No proxy da API Edge, é 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 indicam: "Quando uma solicitação GET chega com /reports
e
/forecasts
no URL, o Edge fará o que você (o desenvolvedor da API) pedir,
usando as políticas que você anexa a esses fluxos.
Este é um exemplo de como dizer ao Edge o que fazer quando uma condição for atendida. Na API a seguir
proxy XML, quando uma solicitação GET é enviada para
https://yourorg-test.apigee.net/mygreatweatherforecast/reports
, o Edge é executado
é o arquivo "XML-to-JSON-1" política 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 é necessário aplicar diferentes tipos de lógica aos recursos /developers aos recursos /apps.
Para fazer isso, adicione dois fluxos condicionais ao proxy da API: /developers
e
/apps
.
Na visualização "Desenvolvimento" do painel de navegação do editor de proxy da API, clique no ícone + ao lado dos padrões no Endpoints de proxy.
Na janela "New Conditional Flow", insira as seguintes configurações principais:
- Nome do fluxo: desenvolvedores
- Tipo de condição: caminho
- 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
- Condition Type: Path e Verb
- Caminho: /apps
- Verb: 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://{org_name}-test.apigee.net/{proxy_path}/apps
fará com que a condição seja avaliada como verdadeira e que esse fluxo, juntamente 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 ... na Comunidade Apigee.
Como modelar URIs hierárquicos
Em alguns casos, você terá recursos hierárquicos da API. Por exemplo, a API dos serviços para desenvolvedores 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
resolverá esses URIs hierárquicos conforme apropriado os recursos da API.
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 de borda costumam querer processar estes dois sufixos de caminho: "/cat
" e
"/cat/
". Isso ocorre porque alguns usuários ou clientes podem chamar sua API com os recursos
no final do caminho, e você precisa conseguir lidar com isso em seu comando
declarações. Esse caso de uso exato
foi discutido na comunidade da Apigee.
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://artomatic-test.apigee.net/matchtest/cat
or
GET http://artomatic-test.apigee.net/matchtest/cat
/
A política é executada? Sim. Em uma expressão regular, a expressão "?
"
significa: corresponde a zero ou a um dos caracteres anteriores. Portanto, tanto
"/cat
" e "/cat/
" são correspondências.
Chamada de API:
GET http://artomatic-test.apigee.net/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. É bom saber que você pode fazer a correspondência de padrões em qualquer string arbitrária ou variável de fluxo, independentemente de ser 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 o JavaRegex, a expressão regular será comparada com toda a string de assunto. 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 da string inteira.
<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, você também pode testar "editor" com o operador "Correspondências":
<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"'
request.header.Content-Type ~~ "(multipart\/related)(; *type="application\/xop\+xml\")"
\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)"