Stai visualizzando la documentazione di Apigee Edge.
Consulta la
documentazione di Apigee X. info
Le istruzioni condizionali sono una struttura di controllo comune in tutti i linguaggi di programmazione. Come un linguaggio di programmazione, la configurazione del proxy API supporta le istruzioni condizionali per flussi, criteri, passaggi e RouteRule. Definendo le istruzioni condizionali, definisci il comportamento dinamico della tua API. Questo comportamento dinamico ti consente di eseguire operazioni come la conversione di XML in JSON solo per i dispositivi mobili o il routing a un URL di backend in base al tipo di contenuti o al verbo HTTP del messaggio di richiesta.
Questo argomento mostra come utilizzare le condizioni per applicare dinamicamente le funzionalità di gestione delle API in fase di runtime, senza scrivere codice.
Configurare le istruzioni condizionali
Il comportamento condizionale viene implementato nei proxy API utilizzando una combinazione di condizioni e variabili. Un'istruzione condizionale viene creata utilizzando un elemento Condition. Di seguito è riportata una condizione vuota:
<Condition></Condition>
Per creare un'istruzione condizionale, aggiungi un operatore condizionale e una variabile per creare la seguente struttura:
<Condition>{variable.name}{operator}{"value"}</Condition>
Gli operatori condizionali supportati includono = (uguale a), != (diverso da)
e > (maggiore di). Per una maggiore leggibilità, puoi anche scrivere le condizioni come
testo: equals, notequals, greaterthan.
Quando lavori con i percorsi URI, puoi utilizzare ~/ o MatchesPath. Puoi
anche trovare corrispondenze con le espressioni regolari JavaRegex con l'operatore ~~.
Le condizioni vengono utilizzate per definire i flussi condizionali del proxy API alle risorse API di backend, descritti in Creare flussi condizionali alle risorse API di backend. Per un elenco completo delle condizioni, consulta Riferimento alle condizioni.
Variabili
Le condizioni funzionano valutando i valori delle variabili. Una variabile è una proprietà di una transazione HTTP eseguita da un proxy API o una proprietà della configurazione del proxy API stesso. Ogni volta che un proxy API riceve una richiesta da un'app, Apigee Edge compila un lungo elenco di variabili associate a elementi quali l'ora di sistema, le informazioni di rete dell'app, le intestazioni HTTP nei messaggi, la configurazione del proxy API, le esecuzioni dei criteri e così via. In questo modo viene creato un contesto avanzato che puoi utilizzare per configurare istruzioni condizionali.
Le variabili utilizzano sempre una notazione con punti. Ad esempio, le intestazioni HTTP nel messaggio di richiesta sono
disponibili come variabili chiamate request.header.{header_name}. Per valutare l'intestazione
Content-type, puoi utilizzare la variabile request.header.Content-type. Ad esempio, request.header.Content-type = "application/json" indica che il tipo di contenuto della richiesta deve essere JSON.
Supponiamo di dover creare un'istruzione condizionale che imponga l'applicazione di una norma
solo quando un messaggio di richiesta è GET. Per creare una condizione che valuti il verbo HTTP
di una richiesta, crea l'istruzione condizionale riportata di seguito. La variabile in questa condizione è
request.verb. Il valore della variabile è GET. L'operatore è
=.
<Condition>request.verb = "GET"</Condition>
<Condition>request.verb equals "GET"</Condition>
Edge utilizza questa istruzione per valutare le condizioni. L'esempio precedente restituisce true se il verbo HTTP associato alla richiesta è GET. Se il verbo HTTP associato alla richiesta è POST, l'istruzione restituisce il valore false.
Per attivare il comportamento dinamico, puoi collegare le condizioni a flussi, passaggi e regole di routing.
Quando colleghi una condizione a un flusso, crei un "flusso condizionale". I flussi condizionali vengono eseguiti solo quando la condizione restituisce il valore true. Puoi allegare tutte le policy che vuoi a un flusso condizionale. Un flusso condizionale ti consente di creare regole di elaborazione altamente specializzate per i messaggi di richiesta o risposta che soddisfano determinati criteri.
Ad esempio, per creare un flusso che viene eseguito solo quando il verbo della richiesta è GET:
<Flows> <Flow name="ExecuteForGETs"> <Condition>request.verb="GET"</Condition> </Flow> </Flows>
Per creare un flusso per i GET e un altro per i POST:
<Flows> <Flow name="ExecuteForGETs"> <Condition>request.verb="GET"</Condition> </Flow> <Flow name="ExecuteForPOSTs"> <Condition>request.verb="POST"</Condition> </Flow> </Flows>
Come mostrato nell'esempio seguente, puoi applicare la condizione al passaggio della norma stesso. La seguente condizione fa sì che il criterio VerifyApiKey venga applicato solo se un messaggio di richiesta è un POST.
<PreFlow name="PreFlow">
<Request>
<Step>
<Condition>request.verb equals "POST"</Condition>
<Name>VerifyApiKey</Name>
</Step>
</Request>
</PreFlow>Una volta definiti questi flussi condizionali, puoi collegarvi dei criteri, consentendo a un proxy API di applicare un insieme di criteri per le richieste GET e un altro insieme di criteri per le richieste POST.
Per informazioni di riferimento complete, consulta le seguenti risorse:
Esempio 1
L'esempio seguente mostra un singolo flusso condizionale denominato Convert-for-devices,
configurato nel flusso di risposta ProxyEndpoint. Aggiungi la condizione come elemento all'entità a cui si applica. In questo esempio, la condizione è un componente del flusso.
Pertanto, il flusso verrà eseguito ogni volta che l'istruzione restituisce il valore true.
<Flows>
<Flow name="Convert-for-devices">
<Condition>(request.header.User-Agent = "Mozilla")</Condition>
<Response>
<Step><Name>ConvertToJSON</Name></Step>
</Response>
</Flow>
</Flows>Per ogni richiesta ricevuta da un'app, Edge memorizza i valori di tutte le intestazioni HTTP presenti come
variabili. Se la richiesta contiene un'intestazione HTTP denominata User-Agent, questa intestazione e
il relativo valore vengono memorizzati come variabile denominata request.header.User-Agent.
Data la configurazione di ProxyEndpoint riportata sopra, Edge controlla il valore della
variabile request.header.User-Agent per verificare se la condizione restituisce
true.
Se la condizione restituisce il valore true, ovvero il valore della variabile
request.header.User-Agent è uguale a Mozilla, il flusso condizionale
viene eseguito e viene applicato il criterio XMLtoJSON chiamato ConvertToJSON. In caso contrario, il flusso
non viene eseguito e la risposta XML viene restituita senza modifiche (in formato XML) all'app
che ha effettuato la richiesta.
Esempio 2
Utilizziamo un esempio specifico in cui devi trasformare il messaggio di risposta da XML a JSON, ma solo per i dispositivi mobili. Innanzitutto, crea la policy che convertirà la risposta in formato XML dell'API Weather in JSON:
<XMLToJSON name="ConvertToJSON"> <Options> </Options> <OutputVariable>response</OutputVariable> <Source>response</Source> </XMLToJSON>
La configurazione dei criteri riportata sopra indica al proxy API di prendere il messaggio di risposta, eseguire una
conversione da XML a JSON con le impostazioni predefinite e quindi scrivere il risultato nel nuovo messaggio di
risposta. (Se stai convertendo un messaggio di richiesta da XML a JSON, imposta entrambi questi valori su request.)
Poiché vuoi convertire le risposte da XML a JSON, devi configurare un flusso di risposte condizionali per eseguire la conversione. Ad esempio, per convertire tutte le risposte da XML a JSON prima che vengano restituite all'app client, configura il seguente flusso di risposta ProxyEndpoint.
<Flows>
<Flow name="Convert-for-devices">
<Response>
<Step><Name>ConvertToJSON</Name></Step>
</Response>
</Flow>
</Flows>Quando richiami l'API utilizzando la richiesta standard, la risposta viene formattata in JSON.
Tuttavia, il tuo obiettivo è convertire i report meteo in JSON solo quando il client richiedente è un dispositivo mobile. Per attivare questo comportamento dinamico, devi aggiungere un'istruzione condizionale al flusso.
Testare il flusso condizionale
In questa richiesta di esempio, l'intestazione HTTP User-Agent è impostata su
Mozilla, facendo in modo che l'istruzione condizionale restituisca true e che il flusso
condizionale Convert-for-devices venga eseguito.
$ curl -H "User-Agent:Mozilla" http://{org_name}-test.apigee.net/weather/forecastrss?w=12797282
oppure, per la stampa in formato pretty print dove è disponibile Python:
$ curl -H "User-Agent:Mozilla" http://{org_name}-test.apigee.net/weather/forecastrss?w=12797282 | python -mjson.tool
Esempio di risposta:
. . .
"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"
}
]
}
. . .Una richiesta inviata senza l'intestazione User-Agent o con un valore diverso da
Mozilla genererà una risposta in formato XML.
$ curl http://{org_name}-test.apigee.net/weather/forecastrss?w=12797282
Viene restituita la risposta XML non modificata.
Esempio di risposta:
<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" />
Corrispondenza di pattern
Questa sezione descrive come utilizzare la corrispondenza di pattern con le condizioni in un flusso Apigee.
Operatori
Questa sezione descrive come utilizzare i seguenti operatori di corrispondenza dei pattern nelle istruzioni condizionali:
- Operatore Corrisponde: corrispondenza semplice dei pattern
- Operatore JavaRegex: controllo più preciso della corrispondenza
- Operatore MatchesPath: corrispondenza frammento percorso
Corrisponde a
Diamo prima un'occhiata all'operatore condizionale "Corrispondenze" o "~". Questi due operatori sono identici: la versione inglese, "Matches", è considerata un'opzione più leggibile.
Riepilogo:l'operatore "Corrispondenze" offre due possibilità. Corrisponde alla stringa letteralmente o esegui una corrispondenza con caratteri jolly con "*". Come puoi immaginare, il carattere jolly corrisponde a zero o più caratteri. Vediamo come funziona.
Il seguente XML mostra una condizione di passaggio. Esegue la policy SomePolicy quando la condizione
restituisce il valore true. In questo esempio, testiamo la variabile proxy.pathsuffix, una
variabile integrata in Edge che memorizza il suffisso del percorso della richiesta. Tuttavia, puoi testare
il valore di qualsiasi variabile di flusso che contenga una stringa. Quindi, in questo caso, se il percorso di base della
richiesta in entrata è /animals e la richiesta è /animals/cat, il
suffisso del percorso è la stringa letterale "/cat".
<PreFlow name="PreFlow">
<Request>
<Step>
<Condition>(proxy.pathsuffix Matches "/cat")</Condition>
<Name>SomePolicy</Name>
</Step>
</Request>
<Response/>
</PreFlow>Domanda: quale suffisso del percorso proxy causerà l'esecuzione di SomePolicy? C'è una sola possibilità.
Chiamata API:
GET http://artomatic-test.apigee.net/matchtest/cat
La policy viene eseguita? Sì, perché il suffisso del percorso proxy corrisponde esattamente a "/cat". Non verrà eseguito se il suffisso è /bat o /dog o
"/" o qualsiasi altro valore.
Ora considera questa istruzione condizionale in cui utilizziamo il carattere jolly
"*":
<Condition>(proxy.pathsuffix Matches "/*at")</Condition>
Chiamata API:
GET http://artomatic-test.apigee.net/matchtest/cat
La policy viene eseguita? Sì, perché il carattere jolly corrisponde a qualsiasi carattere e
"/cat" è una corrispondenza.
Chiamata API:
GET http://artomatic-test.apigee.net/matchtest/bat
La policy viene eseguita? Sì, perché il carattere jolly corrisponde a qualsiasi carattere, "/bat"
è una corrispondenza.
Chiamata API:
GET http://artomatic-test.apigee.net/matchtest/owl
La policy viene eseguita? Certamente no. Anche se il carattere jolly corrisponde a "o",
le lettere "wl" non corrispondono.
Ora spostiamo il carattere jolly alla fine del suffisso:
<Condition>(proxy.pathsuffix Matches "/cat*")</Condition>
Chiamata API:
GET http://artomatic-test.apigee.net/matchtest/cat
La policy viene eseguita? Sì, perché il carattere jolly corrisponde a zero o più caratteri qualsiasi.
Chiamata API:
GET http://artomatic-test.apigee.net/matchtest/bat
La policy viene eseguita? No, "/bat" non è una corrispondenza.
Chiamata API:
GET http://artomatic-test.apigee.net/matchtest/cat123
La policy viene eseguita? Sì, il carattere jolly corrisponde a zero o più caratteri, quindi
"123" produce una corrispondenza.
Chiamata API:
GET http://artomatic-test.apigee.net/matchtest/cat/bird/mouse
La policy viene eseguita? Sì, perché il carattere jolly corrisponde a zero o più caratteri qualsiasi, quindi
"/bird/mouse" produce una corrispondenza. Nota come un'espressione di questo tipo possa causare problemi perché corrisponde a tutto ciò che segue i caratteri letterali.
Domanda: l'operatore Corrispondenze fa distinzione tra maiuscole e minuscole?
Sì. Supponiamo che tu abbia una condizione come questa:
<Condition>(proxy.pathsuffix Matches "/*At")</Condition>
Chiamata API:
GET http://artomatic-test.apigee.net/matchtest/cat
La policy viene eseguita? No, il carattere jolly corrisponde a qualsiasi lettera (indipendentemente dalle maiuscole), ma la "a" minuscola non corrisponde ad "A".
Chiamata API:
GET http://artomatic-test.apigee.net/matchtest/bAt
La policy viene eseguita? Sì, la richiesta corrisponde.
Domanda: come faccio a eseguire l'escape dei caratteri con l'operatore Matches?
Utilizza il carattere percentuale "%" per eseguire l'escape dei caratteri riservati. Ad esempio:
<Condition>(proxy.pathsuffix Matches "/c%*at")</Condition>
Chiamata API:
GET http://artomatic-test.apigee.net/matchtest/cat
La policy viene eseguita? No, l'operatore Corrispondenze cerca la stringa letterale "c*at".
Chiamata API:
GET http://artomatic-test.apigee.net/matchtest/c*at
Domanda:la policy viene eseguita?
Sì, questo percorso, anche se un po' insolito, corrisponde.
JavaRegex
Come puoi vedere, l'operatore "Corrisponde" è ideale per situazioni semplici. ma puoi utilizzare un altro operatore, l'operatore "JavaRegex" o "~~". Questi due sono lo stesso operatore, tranne che JavaRegex è considerato più leggibile. Si chiama JavaRegex perché consente la corrispondenza dei pattern di espressioni regolari ed Edge segue le stesse regole delle classi nel pacchetto java.util.regex nel linguaggio Java. Il funzionamento dell'operatore JavaRegex è molto diverso da quello dell'operatore Corrisponde, quindi è importante non confonderli.
Riepilogo: l'operatore "JavaRegex" consente di utilizzare la sintassi delle espressioni regolari nelle istruzioni condizionali.
Il seguente codice mostra una condizione di passaggio. Esegue la norma SomePolicy se la condizione
restituisce true. In questo esempio, testiamo la variabile proxy.pathsuffix, una variabile
integrata in Edge che memorizza il suffisso del percorso della richiesta. Se il percorso di base della
richiesta in entrata è /animals e la richiesta è /animals/cat, il
suffisso del percorso è la stringa letterale "/cat".
<PreFlow name="PreFlow">
<Request>
<Step>
<Condition>(proxy.pathsuffix JavaRegex "/cat")</Condition>
<Name>SomePolicy</Name>
</Step>
</Request>
<Response/>
</PreFlow>Domanda: quale suffisso del percorso proxy causerà l'esecuzione di SomePolicy? Proprio come con l'operatore Corrisponde, in questo caso c'è una sola possibilità.
Chiamata API:
GET http://artomatic-test.apigee.net/matchtest/cat
La policy viene eseguita? Sì, perché il suffisso del percorso proxy corrisponde esattamente a "/cat". Non verrà eseguito se il suffisso è /bat o /dog o qualsiasi altro valore.
Ora creiamo un'espressione regolare utilizzando il quantificatore "*". Questo quantificatore corrisponde a zero o più del carattere precedente.
<Condition>(proxy.pathsuffix JavaRegex "/c*t")</Condition>
Chiamata API:
GET http://artomatic-test.apigee.net/matchtest/cat
La policy viene eseguita? No! Il quantificatore "*" corrisponde a zero o più del
carattere precedente, ovvero "c".
Chiamata API:
GET http://artomatic-test.apigee.net/matchtest/ccccct
La policy viene eseguita? Sì, perché il carattere jolly corrisponde a zero o più caratteri precedenti.
Successivamente, utilizziamo il quantificatore "?", che corrisponde al carattere precedente una volta o mai.
<Condition>(proxy.pathsuffix JavaRegex "/ca?t")</Condition>
Chiamata API:
GET http://artomatic-test.apigee.net/matchtest/cat
La policy viene eseguita? Sì. Il quantificatore "?" corrisponde a zero o una occorrenza del carattere precedente, ovvero "a".
Chiamata API:
GET http://artomatic-test.apigee.net/matchtest/ct
La policy viene eseguita? Sì. Il quantificatore "?" corrisponde a uno o
nessuno dei caratteri precedenti. In questo caso, non è presente il carattere "a", quindi la
condizione restituisce il valore true.
Chiamata API:
GET http://artomatic-test.apigee.net/matchtest/caat
La policy viene eseguita? No. Il quantificatore "?" corrisponde a uno dei caratteri precedenti, ovvero "a".
Successivamente, utilizziamo lo stile di espressione regolare "[abc]" o "raggruppamento". Corrisponde ai caratteri "a", "b" o "c".
<Condition>(proxy.pathsuffix JavaRegex "/[cbr]at")</Condition>
Chiamata API:
GET http://artomatic-test.apigee.net/matchtest/cat
La policy viene eseguita? Sì. Qui utilizziamo espressioni regolari e l'espressione
"[cbr]" corrisponde a "c", "b" O "r". Anche queste chiamate sono corrispondenze:
GET http://artomatic-test.apigee.net/matchtest/bat
GET http://artomatic-test.apigee.net/matchtest/rat
Ma questa non è una corrispondenza:
GET http://artomatic-test.apigee.net/matchtest/mat
Domanda: l'operatore JavaRegex fa distinzione tra maiuscole e minuscole?
Sì. Supponiamo che tu abbia una condizione come questa:
<Condition>(proxy.pathsuffix JavaRegex "/ca?t")</Condition>
Chiamata API:
GET http://artomatic-test.apigee.net/matchtest/cat
La policy viene eseguita? Sì, l'espressione regolare corrisponde a zero o a uno dei caratteri precedenti, ovvero "a".
Chiamata API:
GET http://artomatic-test.apigee.net/matchtest/cAt
Domanda: i criteri vengono applicati?
No, perché la "A" maiuscola non corrisponde alla "a" minuscola.
MatchesPath
L'operatore MatchesPath può essere specificato anche come "~/". Assomiglia un po' agli operatori
Matches (~) e JavaRegex (~~). Ma MatchesPath è completamente diverso.
Ricorda solo che questo operatore considera un percorso come una serie di parti. Pertanto, se il percorso
è: /animals/cats/wild, puoi considerarlo composto dalle parti
"/animals", "/cats" e "/wild".
L'operatore MatchesPath consente di utilizzare due notazioni con caratteri jolly: un singolo asterisco (*) e un doppio asterisco (**). Il singolo asterisco corrisponde a un elemento del percorso. Il doppio asterisco corrisponde
a uno o più elementi del percorso.
Ecco un esempio. In questo esempio, testiamo la variabile proxy.pathsuffix,
una variabile integrata in Edge che memorizza il suffisso del percorso della richiesta. Tuttavia, puoi
testare il valore di qualsiasi variabile di flusso che contiene una stringa.
<PreFlow name="PreFlow">
<Request>
<Step>
<Condition>(proxy.pathsuffix MatchesPath "/animals/*")</Condition>
<Name>SomePolicy</Name>
</Step>
</Request>
<Response/>
</PreFlow>Domanda: quale suffisso del percorso proxy causerà l'esecuzione di SomePolicy?
Chiamata API:
GET http://artomatic-test.apigee.net/matchtest/animals
Domanda: i criteri vengono applicati?
No, perché la condizione richiede un altro elemento del percorso dopo
"/animals", come specificato da "/*".
Chiamata API:
GET http://artomatic-test.apigee.net/matchtest/animals/
La policy viene eseguita? Sì, il percorso ha un altro elemento (la parte dopo
"/animals/"), ma è vuoto.
Chiamata API:
GET http://artomatic-test.apigee.net/matchtest/animals/cats
La policy viene eseguita? Sì, perché il percorso ha chiaramente un elemento ("/cats")
che segue "/animals"
Chiamata API:
GET http://artomatic-test.apigee.net/matchtest/animals/cats/wild
Domanda: i criteri vengono applicati?
No, perché il singolo asterisco corrisponde a un solo elemento del percorso e
questa API ha più di un elemento dopo "/animals".
Ora utilizziamo il doppio asterisco:
<PreFlow name="PreFlow">
<Request>
<Step>
<Condition>(proxy.pathsuffix MatchesPath "/animals/**")</Condition>
<Name>SomePolicy</Name>
</Step>
</Request>
<Response/>
</PreFlow>Domanda: quale suffisso del percorso proxy causerà l'esecuzione di SomePolicy?
Chiamata API:
GET http://artomatic-test.apigee.net/matchtest/animals
La policy viene eseguita? No, perché la condizione richiede almeno un elemento del percorso successivo
specificato da "/**".
Chiamata API:
GET http://artomatic-test.apigee.net/matchtest/animals/
La policy viene eseguita?
Sì, il percorso ha un altro elemento (la parte dopo
"/animals/"), ma è vuoto.
Chiamata API:
GET http://artomatic-test.apigee.net/matchtest/animals/cats
La policy viene eseguita?
Sì, perché il percorso ha almeno un elemento che segue
"/animals"
Chiamata API:
GET http://artomatic-test.apigee.net/matchtest/animals/cats/wild
La policy viene eseguita?
Sì, perché il percorso ha più di un elemento che segue
"/animals"
Combinazione di asterischi
Puoi utilizzare combinazioni di asterisco singolo (*) e doppio (**) per perfezionare ulteriormente la corrispondenza dei percorsi.
<PreFlow name="PreFlow">
<Request>
<Step>
<Condition>(proxy.pathsuffix MatchesPath "/animals/*/wild/**")</Condition>
<Name>SomePolicy</Name>
</Step>
</Request>
<Response/>
</PreFlow>Chiamata API:
Tutte queste chiamate API produrranno una corrispondenza:
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
Risorse API
I servizi RESTful sono raccolte di risorse API. Una risorsa API è un frammento di percorso URI che identifica un'entità a cui gli sviluppatori possono accedere chiamando la tua API. Ad esempio, se il tuo servizio fornisce report e previsioni meteo, il tuo servizio di backend potrebbe definire due risorse API:
- http://mygreatweatherforecast.com/reports
- http://mygreatweatherforecast.com/forecasts
Quando crei un proxy API (come mostrato in Crea il tuo primo proxy API), come minimo crei un URL di base alias che esegue il mapping al tuo servizio di backend. Ad esempio:
| URL di base del backend | Nuovo URL proxy API/equivalente |
|---|---|
| http://mygreatweatherforecast.com | http://{your_org}-{environment}.apigee.net/mygreatweatherforecast |
A questo punto puoi effettuare chiamate API al backend utilizzando uno dei due URL di base. Ma quando utilizzi l'URL del proxy API, le cose iniziano a farsi interessanti.
Oltre alle analisi API che Edge inizia a raccogliere quando utilizzi il proxy API, i proxy consentono anche di definire flussi condizionali che vengono mappati alle risorse del backend. In sostanza, "Se arriva una chiamata GET alla risorsa /reports, Edge deve fare qualcosa".
L'immagine seguente mostra la differenza di comportamento tra due URL che accedono in definitiva allo stesso backend. Uno è l'URL della risorsa senza proxy, l'altro è un proxy API Edge con un flusso condizionale alla stessa risorsa di backend. Di seguito descriveremo in modo più dettagliato i flussi condizionali.

Come i proxy API vengono mappati a risorse di backend specifiche
Con un URL proxy API mappato all'URL di base del servizio di backend (quando crei il proxy), puoi aggiungere flussi condizionali a risorse specifiche, come le risorse /reports e /forecasts menzionate in precedenza.
Supponiamo che tu voglia che Edge "faccia qualcosa" quando arrivano chiamate alle risorse
/reports o /forecasts. A questo punto non stai dicendo a Edge
cosa fare, ma solo che deve ascoltare le chiamate a queste risorse. Puoi farlo
con le condizioni. Nel proxy API Edge, puoi creare flussi condizionali per
/reports e /forecasts. A scopo concettuale, il seguente XML del proxy API
mostra come potrebbero apparire queste condizioni.
<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>Queste condizioni recitano: "Quando arriva una richiesta GET con /reports e
/forecasts nell'URL, Edge farà tutto ciò che gli dirai (in qualità di sviluppatore di API),
tramite le norme che colleghi a questi flussi.
Ecco un esempio di come indicare a Edge cosa fare quando una condizione viene soddisfatta. Nel seguente XML del proxy API, quando viene inviata una richiesta GET a https://yourorg-test.apigee.net/mygreatweatherforecast/reports, Edge esegue il criterio "XML-to-JSON-1" nella risposta.
<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>Oltre a questi flussi condizionali facoltativi, ogni proxy API include anche due flussi predefiniti: un <PreFlow> eseguito prima dei flussi condizionali e un
<PostFlow> eseguito dopo i flussi condizionali. Sono utili per
eseguire i criteri quando viene effettuata qualsiasi chiamata a un proxy API. Ad esempio, se vuoi
verificare la chiave API di un'app a ogni chiamata, indipendentemente dalla risorsa di backend a cui si accede, puoi
inserire un criterio Verifica chiave API in <PreFlow>. Per saperne di più sui flussi, consulta la sezione
Configurazione dei flussi.
Crea flussi condizionali alle risorse di backend
La definizione di flussi condizionali per le risorse di backend in un proxy API è completamente facoltativa. Tuttavia, questi flussi condizionali ti consentono di applicare una gestione e un monitoraggio granulari.
Potrai:
- Applica la gestione in modo da riflettere la semantica del modello API
- Applica criteri e comportamenti basati su script a singoli percorsi delle risorse (URI)
- Raccogli metriche granulari per i servizi Analytics
Ad esempio, supponiamo che tu debba applicare diversi tipi di logica alle risorse di backend /developers e /apps.
Per farlo, aggiungi due flussi condizionali nel proxy API: /developers e
/apps.
Nella visualizzazione Sviluppo del riquadro di navigazione dell'editor del proxy API, fai clic sull'icona + accanto a default in Proxy Endpoint.
![]()
Nella finestra "Nuovo flusso condizionale", inserisci le seguenti configurazioni chiave:
- Nome flusso: Sviluppatori
- Tipo di condizione: percorso
- Percorso: /developers

La condizione verrà attivata (e i criteri verranno eseguiti) se una chiamata viene inviata al proxy con /developers alla fine dell'URI.
Ora aggiungi un flusso condizionale per /apps e supponi di voler attivare la condizione sia sull'URI sia sul verbo POST in una richiesta. La configurazione prevede l'impostazione di quanto segue:
- Nome del flusso: app
- Tipo di condizione: percorso e verbo
- Percorso: /apps
- Verbo: PUBBLICA

La condizione verrà attivata (e i criteri verranno eseguiti) se viene inviata una chiamata al proxy con /apps alla fine dell'URI e un verbo POST.
Nel riquadro di navigazione, vedrai nuovi flussi per App e Sviluppatori.

Seleziona uno dei flussi per visualizzare la configurazione del flusso condizionale nella visualizzazione del codice dell'editor del proxy 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>
Come puoi vedere, le risorse API sono semplicemente flussi condizionali che valutano il percorso URI della richiesta in entrata. (La variabile proxy.pathsuffix identifica l'URI della richiesta che segue il BasePath configurato nella configurazione ProxyEndpoint.)
Ogni risorsa API che definisci viene implementata da un flusso condizionale nel proxy API. (Vedi Configurazione dei flussi.)
Dopo aver eseguito il deployment del proxy API nell'ambiente di test, la seguente richiesta:
http://{org_name}-test.apigee.net/{proxy_path}/appsfarà in modo che la condizione restituisca il valore true e che questo flusso, insieme a tutte le policy associate, venga eseguito.
La seguente condizione di esempio utilizza un'espressione regolare Java per riconoscere le chiamate effettuate alla risorsa /apps con o senza una barra finale (/apps o /apps/**):
<Condition>(proxy.pathsuffix JavaRegex "/apps(/?)") and (request.verb = "POST")</Condition>
Per saperne di più su questo tipo di condizione, vedi Come trovare corrispondenze indipendentemente ... nella community Apigee.
Modellazione di URI gerarchici
In alcuni casi, avrai risorse API gerarchiche. Ad esempio, l'API Developer Services fornisce un metodo per elencare tutte le app appartenenti a uno sviluppatore. Il percorso URI è:
/developers/{developer_email}/appsPotresti avere risorse in cui viene generato un ID univoco per ogni entità di una raccolta, che a volte viene annotato come segue:
/genus/:id/species
Questo percorso si applica in egual misura ai due URI seguenti:
/genus/18904/species /genus/17908/species
Per rappresentare questa struttura in una risorsa API, puoi utilizzare i caratteri jolly. Ad esempio:
/developers/*/apps
/developers/*example.com/apps
/genus/*/species
risolverà questi URI gerarchici come risorse API in modo appropriato.
In alcuni casi, soprattutto per le API con una struttura gerarchica profonda, potresti voler risolvere tutto ciò che si trova sotto un determinato frammento di URI. A questo scopo, utilizza un carattere jolly doppio asterisco nella definizione della risorsa. Ad esempio, se definisci la seguente risorsa API:/developers/**
Questa risorsa API risolverà i seguenti percorsi URI:
/developers/{developer_email}/apps
/developers/{developer_email}/keys
/developers/{developer_email}/apps/{app_id}/keysEcco l'aspetto della condizione del flusso condizionale nella definizione del proxy API:
<Condition>(proxy.pathsuffix MatchesPath "/developers/**") and (request.verb = "POST")</Condition>
Altri esempi
Condizione allegata 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>
Condizione associata a una policy
<Step> <!--the policy MaintenancePolicy only executes if the response status code is exactly 503--> <Condition>response.status.code = 503</Condition> <Name>MaintenancePolicy</Name> </Step>
Flusso condizionale
<!-- 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>
Operatori di esempio nelle condizioni
Ecco alcuni esempi di operatori utilizzati per creare condizioni:
request.header.content-type = "text/xml"request.header.content-length < 4096 && request.verb = "PUT"response.status.code = 404 || response.status.code = 500request.uri MatchesPath "/*/statuses/**"request.queryparam.q0 NotEquals 10
Un esempio pratico: ignora "/" alla fine di un percorso
Gli sviluppatori di Edge in genere vogliono gestire entrambi i suffissi del percorso: "/cat" e
"/cat/". Questo perché alcuni utenti o client potrebbero chiamare la tua API con la barra
aggiuntiva alla fine del percorso e devi essere in grado di gestirla nelle istruzioni
condizionali. Questo caso d'uso esatto
è stato discusso nella community Apigee.
Se preferisci, puoi ottenere questo risultato senza utilizzare le espressioni regolari in questo modo:
<PreFlow name="PreFlow">
<Request>
<Step>
<Condition>((proxy.pathsuffix = "/cat") OR (proxy.pathsuffix = "/cat/")</Condition>
<Name>SomePolicy</Name>
</Step>
</Request>
<Response/>
</PreFlow>Questa è una buona opzione. Sia chiaro e leggibile.
Puoi fare la stessa cosa con le espressioni regolari, ma in questo modo. Le parentesi vengono utilizzate per raggruppare la parte dell'espressione regolare dell'istruzione, ma non sono obbligatorie.
<Condition>(proxy.pathsuffix JavaRegex "/cat(/?)"</Condition>
Chiamate API:
GET http://artomatic-test.apigee.net/matchtest/cat
or
GET http://artomatic-test.apigee.net/matchtest/cat/
La policy viene eseguita? Sì. Tieni presente che in un'espressione regolare, il carattere "?"
significa: corrisponde a zero o a uno dei caratteri precedenti. Pertanto, sia
"/cat" che "/cat/" sono corrispondenze.
Chiamata API:
GET http://artomatic-test.apigee.net/matchtest/cat/spotted
La policy viene eseguita? No. L'espressione regolare corrisponde a zero o a una sola occorrenza del carattere precedente e non è consentito nient'altro.
Corrispondenza di stringhe arbitrarie con JavaRegex
In tutti gli esempi di questo argomento, mostriamo come abbinare una delle variabili di flusso integrate: proxy.pathsuffix. È utile sapere che puoi eseguire la corrispondenza di pattern su qualsiasi stringa arbitraria o variabile di flusso, indipendentemente dal fatto che si tratti di una variabile di flusso integrata come proxy.pathsuffix.
Se, ad esempio, hai una condizione che verifica una stringa arbitraria, magari una stringa restituita in un payload di backend o una stringa restituita da una ricerca del server di autenticazione, puoi utilizzare operatori di corrispondenza per testarla. Se utilizzi JavaRegex, l'espressione regolare verrà confrontata con l'intera stringa dell'oggetto. Se l'oggetto è "abc" e l'espressione regolare è "[a-z]", non viene trovata alcuna corrispondenza, perché "[a-z]" corrisponde esattamente a un carattere alfabetico. L'espressione "[a-z]+" funziona, così come "[a-z]*" e "[a-z]{3}.
Vediamo un esempio concreto. Supponiamo che il server di autenticazione restituisca un elenco di ruoli come una stringa delimitata da virgole: "editor, author, guest".
Per testare la presenza del ruolo Editor, questa costruzione non funzionerà, perché "editor" è solo una parte dell'intera stringa.
<Condition>returned_roles ~~ "editor"</Condition>
Tuttavia, questa costruzione funzionerà:
<Condition>returned_roles ~~ ".*\beditor\b.*")</Condition>
Funziona perché tiene conto delle interruzioni di parola e di qualsiasi altra parte della stringa con il prefisso e il suffisso .*
In questo esempio, puoi anche testare "editor" con l'operatore Corrisponde a:
<Condition>returned_roles ~~ "*editor*")</Condition>
Tuttavia, nei casi in cui è necessaria una maggiore precisione, JavaRegex è spesso una scelta migliore.
Escape delle virgolette doppie nelle espressioni JavaRegex
La sintassi della condizione richiede che un'espressione JavaRegex sia racchiusa tra virgolette doppie; pertanto, se hai un'espressione Regex che include virgolette doppie, devi trovare un modo alternativo per farle corrispondere. La risposta è Unicode. Ad esempio, supponiamo di passare un'intestazione che include le virgolette doppie, come la seguente:-H 'content-type:multipart/related; type="application/xop+xml"'
request.header.Content-Type ~~ "(multipart\/related)(; *type="application\/xop\+xml\")"
\u0022. Ad esempio,
la seguente espressione è valida e produce il risultato previsto:
request.header.Content-Type ~~ "(multipart\/related)(; *type=\u0022application\/xop\+xml\u0022)"