Condizioni con variabili di flusso

Stai visualizzando la documentazione di Apigee Edge.
Vai alla documentazione di Apigee X.
informazioni

Le dichiarazioni condizionali sono una struttura di controllo comune in tutti i linguaggi di programmazione. Analogamente a un linguaggio di programmazione, la configurazione proxy API supporta istruzioni condizionali per flussi, criteri, passaggi e routeRules. Con la definizione delle istruzioni condizionali, definisci il comportamento dinamico dell'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 conditions e conditions. Un'istruzione condizionale viene creata utilizzando un elemento Condition. Di seguito è 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), != (non uguale) e > (maggiore di). Per una migliore leggibilità, puoi anche scrivere le condizionali come testo: equals, notequals, greaterthan.

Quando lavori con i percorsi URI, puoi utilizzare ~/ o MatchesPath. Puoi anche associare le espressioni regolari JavaRegex all'operatore ~~.

Le condizioni vengono utilizzate per definire i flussi condizionali del proxy API verso le risorse dell'API di backend, come descritto in Creare flussi condizionali verso le risorse dell'API di backend. Per un elenco completo delle condizionali, consulta la documentazione di riferimento sulle condizioni.

Variabili

Le condizioni svolgono il loro lavoro valutando i valori delle variabili. Una variabile è una proprietà di una transazione HTTP eseguita da un proxy API o una proprietà della configurazione di un proxy API. Ogni volta che un proxy API riceve una richiesta da un'app, Apigee Edge compila un lungo elenco di variabili associate a elementi come l'ora di sistema, le informazioni di rete dell'app, le intestazioni HTTP dei 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 puntata. Ad esempio, le intestazioni HTTP nel messaggio di richiesta sono disponibili come variabili chiamate request.header.{header_name}. Quindi, per valutare l'intestazione Content-type, potresti utilizzare la variabile request.header.Content-type. Ad esempio, request.header.Content-type = "application/json" indica che il tipo di contenuti della richiesta deve essere JSON.

Immagina di dover creare un'istruzione condizionale che farà applicare un criterio solo quando un messaggio di richiesta è un GET. Per creare una condizione che valuti il verbo HTTP di una richiesta, crea l'istruzione condizionale di seguito. La variabile in questa condizione è request.verb. Il valore della variabile è GET. L'operatore è =.

<Condition>request.verb = "GET"</Condition>
Puoi utilizzare anche:
<Condition>request.verb equals "GET"</Condition>

Edge utilizza tale 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 false.

Per abilitare il comportamento dinamico, puoi collegare le condizioni a Flussi, Passi e RouteRules.

Quando colleghi una condizione a un flusso, crei un "flusso condizionale". I flussi condizionali vengono eseguiti solo quando la condizione è valutata come true. Puoi collegare tutti i criteri che vuoi a un flusso condizionale. Un flusso condizionale consente di creare regole di elaborazione altamente specializzate per i messaggi di richiesta o risposta che soddisfano determinati criteri.

Ad esempio, per creare un Flow che venga eseguito solo quando il verbo della richiesta è GET:

<Flows>
  <Flow name="ExecuteForGETs">
  <Condition>request.verb="GET"</Condition>
  </Flow>
</Flows>

Per creare un flusso per 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 di seguito, puoi applicare la condizione al passaggio relativo alle norme. La condizione seguente causa l'applicazione del criterio VerificationApiKey solo se un messaggio di richiesta è POST.

<PreFlow name="PreFlow">
    <Request>
        <Step>
            <Condition>request.verb equals "POST"</Condition>
            <Name>VerifyApiKey</Name>
        </Step>
    </Request>
</PreFlow>

Dopo aver definito questi flussi condizionali, puoi collegarli ai criteri, abilitando un proxy API per 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 la condizione. In questo esempio, la condizione è un componente del flusso. Di conseguenza, il flusso viene eseguito ogni volta che l'istruzione restituisce 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 archivia i valori di tutte le intestazioni HTTP presenti come variabili. Se la richiesta contiene un'intestazione HTTP denominata User-Agent, questa e il relativo valore vengono archiviati come variabile denominata request.header.User-Agent.

Data la configurazione ProxyEndpoint sopra, Edge controlla il valore della variabile request.header.User-Agent per verificare se la condizione è considerata true.

Se la condizione restituisce true, ovvero il valore della variabile request.header.User-Agent è uguale a Mozilla, viene eseguito il flusso condizionale e viene applicato il criterio XMLtoJSON denominato ConvertToJSON. In caso contrario, il Flow non viene eseguito e la risposta XML viene restituita senza modifiche (in formato XML) all'app che ha inviato 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 il criterio che convertirà la risposta in formato XML dall'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 ricevere il messaggio di risposta, eseguire una conversione da XML a JSON con le impostazioni predefinite e scrivere il risultato nel nuovo messaggio di risposta. Se stai convertendo un messaggio di richiesta da XML a JSON, è sufficiente impostare entrambi questi valori su request.

Poiché vuoi convertire le risposte da XML a JSON, devi configurare un flusso di risposta condizionale 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 è formattata in JSON.

Tuttavia, il tuo obiettivo è convertire i bollettini meteo in JSON solo se il client che ha inviato la richiesta è un dispositivo mobile. Per abilitare questo comportamento dinamico, devi aggiungere un'istruzione condizionale al flusso.

Testa il flusso condizionale

In questa richiesta di esempio, l'intestazione HTTP User-Agent è impostata su Mozilla, generando così la valutazione dell'istruzione condizionale su true e l'esecuzione del flusso condizionale Convert-for-devices.

$ curl -H "User-Agent:Mozilla" http://{org_name}-test.apigee.net/weather/forecastrss?w=12797282

oppure, per eseguire operazioni di stampa "famiglia" 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 dei pattern con le condizioni in un flusso Apigee.

Operatori

Questa sezione descrive come utilizzare i seguenti operatori di corrispondenza di pattern nelle istruzioni condizionali:

Corrisponde a

Esaminiamo innanzitutto l'operatore condizionale "Corrisponde a" o "~". Questi due operatori sono gli stessi. La versione in inglese, "Matches", è considerata più leggibile.

Riepilogo: l'operatore "Corrispondenze" offre due possibilità. Trova la corrispondenza letterale della stringa o inserisci una corrispondenza con caratteri jolly con "*". Come previsto, il carattere jolly corrisponde a zero o più caratteri. Vediamo come funziona.

Il seguente codice XML mostra una condizione Passaggio. Esegue il criterio SomePolicy quando 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. Tuttavia, puoi verificare il valore di qualsiasi variabile di flusso contenente 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

Il criterio viene eseguito? Sì, perché il suffisso del percorso proxy corrisponde esattamente a "/cat". Non verrà eseguito se il suffisso è /bat o /dog, "/" o altro.

Considera ora questa affermazione condizionale in cui utilizziamo il carattere jolly "*":

<Condition>(proxy.pathsuffix Matches "/*at")</Condition>

Chiamata API:

GET http://artomatic-test.apigee.net/matchtest/cat

Il criterio viene eseguito? Sì, perché il carattere jolly corrisponde a qualsiasi carattere e "/cat" è una corrispondenza.

Chiamata API:

GET http://artomatic-test.apigee.net/matchtest/bat

Il criterio viene eseguito? Sì, poiché il carattere jolly corrisponde a qualsiasi carattere, "/bat" è una corrispondenza.

Chiamata API:

GET http://artomatic-test.apigee.net/matchtest/owl

Il criterio viene eseguito? Certo che 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

Il criterio viene eseguito? Sì, perché il carattere jolly corrisponde a zero o più caratteri.

Chiamata API:

GET http://artomatic-test.apigee.net/matchtest/bat

Il criterio viene eseguito? No, "/bat" non è una corrispondenza.

Chiamata API:

GET http://artomatic-test.apigee.net/matchtest/cat123

Il criterio viene eseguito? Sì, il carattere jolly corrisponde a zero o più caratteri, pertanto "123" produce una corrispondenza.

Chiamata API:

GET http://artomatic-test.apigee.net/matchtest/cat/bird/mouse

Il criterio viene eseguito? Sì, perché il carattere jolly corrisponde a zero o più caratteri, quindi "/bird/mouse" produce una corrispondenza. Nota come un'espressione come questa possa causare problemi perché corrisponde a tutto ciò che segue i caratteri letterali.

Domanda: l'operatore di corrispondenza è sensibile alle maiuscole?

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

Il criterio viene eseguito? No, il carattere jolly corrisponde a qualsiasi lettera (indipendentemente dalle maiuscole e minuscole), ma la "a" minuscola non corrisponde alla "A".

Chiamata API:

GET http://artomatic-test.apigee.net/matchtest/bAt

Il criterio viene eseguito? Sì, la richiesta corrisponde.

Domanda: come faccio a eseguire l'escape dei caratteri con l'operatore Corrispondenze?

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

Il criterio viene eseguito? No, l'operatore Matches cerca la stringa letterale "c*at".

Chiamata API:

GET http://artomatic-test.apigee.net/matchtest/c*at

Question:Il criterio viene eseguito?

Sì, questo percorso, anche se un po' insolito, corrisponde.

JavaRegex

Come puoi vedere, l'operatore "Matches" è ideale in situazioni semplici. Tuttavia, puoi utilizzare un altro operatore, l'operatore "JavaRegex" o "~~". Questi due operatori sono lo stesso operatore, tranne per il fatto che JavaRegex è considerato più leggibile. Si chiama JavaRegex perché consente la corrispondenza dei pattern di espressioni regolari e Edge segue le stesse regole delle classi nel pacchetto java.util.regex nel linguaggio Java. Il funzionamento dell'operatore JavaRegex è molto diverso dall'operatore Corrispondenze, quindi è importante non confondere le due cose.

Riepilogo: l'operatore "JavaRegex" consente di utilizzare la sintassi delle espressioni regolari nelle istruzioni condizionali.

Il codice seguente mostra una condizione Passaggio. Esegue il criterio 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? Come per l'operatore Corrispondenze, in questo caso c'è una sola possibilità.

Chiamata API:

GET http://artomatic-test.apigee.net/matchtest/cat

Il criterio viene eseguito? Sì, perché il suffisso del percorso proxy corrisponde esattamente a "/cat". Non verrà eseguito se il suffisso è /bat o /dog o altro.

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

Il criterio viene eseguito? No! Il quantificatore "*" corrisponde a zero o più del carattere precedente, ovvero "c".

Chiamata API:

GET http://artomatic-test.apigee.net/matchtest/ccccct

Il criterio viene eseguito? Sì, perché il carattere jolly corrisponde a zero o più dei caratteri precedenti.

Successivamente, utilizziamo il quantificatore "?", che corrisponde una volta al carattere che lo precede o non corrisponde affatto.

<Condition>(proxy.pathsuffix JavaRegex "/ca?t")</Condition>

Chiamata API:

GET http://artomatic-test.apigee.net/matchtest/cat

Il criterio viene eseguito? Sì. Il quantificatore "?" corrisponde a zero o a una occorrenza del carattere precedente, che è "a".

Chiamata API:

GET http://artomatic-test.apigee.net/matchtest/ct

Il criterio viene eseguito? Sì. Il quantificatore "?" corrisponde a uno o nessuno del carattere precedente. In questo caso, non è presente un carattere "a", quindi la condizione restituisce true.

Chiamata API:

GET http://artomatic-test.apigee.net/matchtest/caat

Il criterio viene eseguito? No. Il quantificatore "?" corrisponde a uno dei caratteri precedenti, che è "a".

Successivamente, utilizziamo lo stile "[abc]" o di "raggruppamento" dell'espressione regex. Corrisponde ai caratteri "a", "b" o "c".

<Condition>(proxy.pathsuffix JavaRegex "/[cbr]at")</Condition>

Chiamata API:

GET http://artomatic-test.apigee.net/matchtest/cat

Il criterio viene eseguito? Sì. Stiamo utilizzando le espressioni regolari qui e l'espressione "[cbr]" corrisponde a "c", "b" OR "r". Anche queste chiamate corrispondono:

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

Il criterio viene eseguito? 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: il criterio viene eseguito?

No, perché la "A" maiuscola non corrisponde alla "a" in lettere minuscole.

MatchesPath

L'operatore MatchesPath può essere specificato anche in questo modo "~/". Assomiglia agli operatori Matches (~) e JavaRegex (~~). MatchesPath è però completamente diverso.

Ricorda però che questo operatore considera un percorso come una serie di parti. Pertanto, se il percorso è /animals/cats/wild, puoi considerare il percorso come costituito dalle parti "/animals", "/cats" e "/wild".

L'operatore MatchesPath consente di utilizzare due notazioni di caratteri jolly: un singolo asterisco (*) e un doppio (**). Il singolo asterisco corrisponde a un elemento del percorso. Il doppio asterisco corrisponde a uno o più elementi del percorso.

Facciamo 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 contenente 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: il criterio viene eseguito?

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/

Il criterio viene eseguito? Sì, il percorso ha un altro elemento (la parte dopo "/animals/"), ma è semplicemente vuoto.

Chiamata API:

GET http://artomatic-test.apigee.net/matchtest/animals/cats

Il criterio viene eseguito? Sì, perché il percorso contiene chiaramente un elemento ("/cats") che segue "/animals"

Chiamata API:

GET http://artomatic-test.apigee.net/matchtest/animals/cats/wild

Domanda: il criterio viene eseguito?

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

Il criterio viene eseguito? No, perché la condizione richiede almeno un elemento del percorso seguente specificato da "/**".

Chiamata API:

GET http://artomatic-test.apigee.net/matchtest/animals/

Il criterio viene eseguito?

Sì, il percorso ha un altro elemento (la parte dopo "/animals/"), ma è semplicemente vuoto.

Chiamata API:

GET http://artomatic-test.apigee.net/matchtest/animals/cats

Il criterio viene eseguito?

Sì, perché il percorso ha almeno un elemento che segue "/animals"

Chiamata API:

GET http://artomatic-test.apigee.net/matchtest/animals/cats/wild

Il criterio viene eseguito?

Sì, perché il percorso ha più di un elemento che segue "/animals"

Combinazione di asterischi

Puoi utilizzare combinazioni di asterischi singoli e doppi (**) per perfezionare ulteriormente la corrispondenza del percorso.

    <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 alcune entità a cui gli sviluppatori possono accedere chiamando la tua API. Ad esempio, se il tuo servizio fornisce previsioni meteo e previsioni meteo, il 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 stai creando un URL di base alias che mappa al tuo servizio di backend. Ad esempio:

URL di base del backend URL del proxy API nuovo/equivalente
http://mygreatweatherforecast.com http://{your_org}-{environment}.apigee.net/mygreatweatherforecast

A questo punto puoi effettuare chiamate API al tuo backend utilizzando entrambi gli URL di base. Ma quando utilizzi l'URL del proxy API, le cose iniziano a diventare interessanti.

Oltre alle analisi delle API che Edge inizia a raccogliere quando utilizzi il proxy API, i proxy consentono anche di definire flussi condizionali che mappano alle risorse nel tuo backend. In sostanza, "se arriva una chiamata GET alla risorsa /reports, Edge dovrebbe fare qualcosa".

L'immagine seguente mostra la differenza di comportamento tra due URL che alla fine accedono 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, vengono descritti in maggiore dettaglio i flussi condizionali.

Modalità di mappatura dei proxy API a risorse di backend specifiche

Con un URL del proxy API mappato all'URL di base del servizio di backend (quando crei il proxy), puoi aggiungere flussi condizionali a risorse specifiche, ad esempio le risorse /reports e /forecasts menzionate in precedenza.

Supponiamo che tu voglia fare in modo che Edge "svolga qualcosa" quando ricevi chiamate alle risorse /reports o /forecasts. A questo punto non stai dicendo a Edge cosa fare, ma solo che dovrebbe ascoltare le chiamate a quelle risorse. Puoi farlo in base alle condizioni. Nel proxy API Edge, puoi creare flussi condizionali per /reports e /forecasts. A fini concettuali, il seguente XML del proxy API mostra l'aspetto di 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 dicono: "Quando arriva una richiesta GET con /reports e /forecasts nell'URL, Edge farà ciò che lo sviluppatore di API le ha detto, tramite i criteri che colleghi a questi flussi.

Ecco un esempio in cui indichi a Edge cosa fare quando una condizione è 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 l'esecuzione di criteri quando viene effettuata una chiamata qualsiasi 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 accedi, puoi inserire un criterio di verifica chiave API su <PreFlow>. Per saperne di più sui flussi, consulta Configurazione dei flussi.

crea flussi condizionali verso le risorse di backend

La definizione di flussi condizionali alle risorse di backend in un proxy API è del tutto facoltativa. Tuttavia, questi flussi condizionali ti consentono di applicare una gestione e un monitoraggio granulari.

Sarai in grado di:

  • Applica la gestione in modo che rifletta la semantica del tuo modello API
  • Applica criteri e comportamento basato su script a singoli percorsi delle risorse (URI)
  • Raccogliere metriche granulari per i servizi di analisi

Ad esempio, immagina di dover applicare tipi diversi di logica al backend /developers alle risorse /apps.

Per farlo, aggiungi due flussi condizionali nel tuo proxy API: /developers e /apps.

Nella visualizzazione Sviluppo del riquadro di navigazione dell'editor proxy API, fai clic sull'icona + accanto al valore predefinito in Endpoint proxy.

Nella finestra "Nuovo flusso condizionale", devi inserire le seguenti configurazioni chiave:

  • Nome flusso: sviluppatori
  • Tipo di condizione: Path
  • Percorso: /developers

La condizione viene attivata (e i criteri verranno eseguiti) se viene inviata una chiamata al proxy con /developers alla fine dell'URI.

Ora aggiungi un flusso condizionale per /apps e supponiamo che tu voglia che la condizione venga attivata sia sull'URI sia sul verbo POST in una richiesta. La configurazione prevede l'impostazione di quanto segue:

  • Nome flusso: App
  • Tipo di condizione: Percorso e Verbo
  • Percorso: /apps
  • Verbo: POST

La condizione viene 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, vengono visualizzati i nuovi flussi per App e Sviluppatori.

Seleziona uno dei flussi per visualizzare la configurazione dei flussi condizionale nella visualizzazione codice dell'editor 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 Configurare i flussi.)

Dopo aver eseguito il deployment del proxy API nell'ambiente di test, viene richiesta la seguente richiesta:

http://{org_name}-test.apigee.net/{proxy_path}/apps

farà sì che la condizione restituisca il valore true e questo flusso, insieme a tutti i criteri associati, verrà eseguito.

La condizione di esempio seguente 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 ulteriori informazioni su questo tipo di condizione, consulta Come eseguire l'abbinamento indipendentemente ... nella community Apigee.

URI gerarchici di modellazione

In alcuni casi, avrai risorse API gerarchiche. Ad esempio, l'API Developer Services fornisce un metodo per elencare tutte le app che appartengono a uno sviluppatore. Il percorso dell'URI è:

/developers/{developer_email}/apps

Potresti avere risorse in cui viene generato un ID univoco per ogni entità in una raccolta, a volte annotata come segue:

/genus/:id/species

Questo percorso si applica anche 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 più gerarchiche, potresti voler semplicemente risolvere tutto ciò che si trova al di sotto di un determinato frammento URI. Per farlo, 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}/keys

Ecco come apparirà la condizione di flusso condizionale nella definizione del proxy API:

<Condition>(proxy.pathsuffix MatchesPath "/developers/**") and (request.verb = "POST")</Condition>

Altri esempi

Condizione collegata 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 un criterio

<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 in condizioni

Di seguito sono riportati 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 = 500
  • request.uri MatchesPath "/*/statuses/**"
  • request.queryparam.q0 NotEquals 10

Esempio pratico: ignora "/" alla fine di un percorso

Gli sviluppatori periferici di solito vogliono gestire entrambi questi suffissi di percorso: "/cat" e "/cat/". Questo perché alcuni utenti o client potrebbero chiamare la tua API con la barra aggiuntiva alla fine del percorso, perciò devi essere in grado di gestirla nelle istruzioni condizionali. Questo esatto caso d'uso è stato discusso nella community di Apigee.

Se preferisci, puoi ottenere questo risultato senza utilizzare le espressioni regolari come segue:

    <PreFlow name="PreFlow">
        <Request>
            <Step>
                <Condition>((proxy.pathsuffix = "/cat") OR (proxy.pathsuffix = "/cat/")</Condition>
                <Name>SomePolicy</Name>
            </Step>
        </Request>
        <Response/>
    </PreFlow>

Si tratta di una buona opzione. Sia chiara e leggibile.

Puoi fare la stessa cosa con le espressioni regolari, ma così. Le parentesi vengono utilizzate per raggruppare la parte regex 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

Il criterio viene eseguito? 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

Il criterio viene eseguito? No. L'espressione regolare corrisponde a zero o a una sola occorrenza del carattere precedente; nessun altro è consentito.

Corrispondenza di stringhe arbitrarie con JavaRegex

In tutti gli esempi di questo argomento, mostriamo come trovare una corrispondenza con una delle variabili di flusso integrate: proxy.pathsuffix. È bene sapere che puoi creare corrispondenze di pattern su qualsiasi stringa o variabile di flusso arbitraria, che si tratti o meno di una variabile di flusso integrata come proxy.pathsuffix.

Se, ad esempio, hai una condizione che verifica una stringa arbitraria, ad esempio una stringa restituita in un payload di backend o una stringa restituita da una ricerca del server di autenticazione, puoi utilizzare gli operatori corrispondenti per verificarla. Se utilizzi JavaRegex, l'espressione regolare verrà confrontata con l'intera stringa oggetto. Se l'oggetto è "abc" e l'espressione regolare è "[a-z]", non esiste alcuna corrispondenza, perché "[a-z]" corrisponde esattamente a un carattere alfa. L'espressione "[a-z]+" funziona, così come "[a-z]*" e "[a-z]{3}.

Vediamo un esempio concreto. Supponi che il server di autenticazione restituisca un elenco di ruoli sotto forma di stringa, senza virgole, come "editor, author, guest".

Per verificare la presenza del ruolo Editor, questa struttura non funzionerà, perché "editor" è solo una parte dell'intera stringa.

<Condition>returned_roles ~~ "editor"</Condition>

Tuttavia, questa struttura funzionerà:

<Condition>returned_roles ~~ ".*\beditor\b.*")</Condition>

Funziona perché prende in considerazione le interruzioni di parola e qualsiasi altra parte della stringa con prefisso .* e suffisso.

In questo esempio, puoi anche testare "editor" con l'operatore Corrispondenze:

<Condition>returned_roles ~~ "*editor*")</Condition>

Tuttavia, nei casi in cui è necessaria una maggiore precisione, JavaRegex è spesso una scelta migliore.

Utilizzo di caratteri di escape per le 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 usare un modo alternativo per trovare la corrispondenza tra virgolette. La risposta è Unicode. Ad esempio, supponiamo di passare un'intestazione che include virgolette doppie, come la seguente:
 -H 'content-type:multipart/related; type="application/xop+xml"'
Se provi a trovare una corrispondenza con l'intestazione in una condizione regex, verrà visualizzato un errore Condizione non valida perché l'espressione include le virgolette doppie:
request.header.Content-Type ~~ "(multipart\/related)(; *type="application\/xop\+xml\")"
La soluzione consiste nel sostituire le virgolette doppie basate su ASCII con l'equivalente Unicode \u0022. Ad esempio, la seguente espressione è valida e produce il risultato previsto:
request.header.Content-Type ~~ "(multipart\/related)(; *type=\u0022application\/xop\+xml\u0022)"