Utilizzo della composizione dei criteri

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

In questo argomento, imparerai a creare un mashup utilizzando la composizione delle norme. La composizione dei criteri è un pattern proxy Apigee che consente di combinare i risultati di più destinazioni di backend in un'unica risposta utilizzando i criteri.

Per una panoramica generale della composizione dei criteri, consulta la sezione "Il modello di composizione dei criteri" in Pattern API Proxy Cookbook.

Scarica e prova il codice campione

Informazioni su questo esempio di libro di ricette

Questo esempio di ricettario illustra un pattern proxy API chiamato composizione delle norme. Questo pattern fornisce un modo (non ci sono altri) per eseguire il mashup dei dati da più origini di backend. Più in generale, questo argomento mostra come combinare e concatenare i criteri per produrre un risultato desiderato. Per una panoramica generale di questo pattern e di altri pattern correlati, consulta i pattern del manuale di istruzioni sul proxy API.

L'esempio discusso qui utilizza la composizione dei criteri per combinare i dati di queste due API pubbliche separate:

  • L'API Google Geocoding: questa API converte gli indirizzi (come "1600 Amphitheatre Parkway, Mountain View, CA") in coordinate geografiche (come latitudine 37.423021 e longitudine -122.083739).
  • API Google Elevation Questa API fornisce una semplice interfaccia per eseguire query sulle località della Terra per ottenere dati sull'altitudine. In questo esempio, le coordinate restituite dall'API Geocoding verranno utilizzate come input in questa API.

Gli sviluppatori di app chiameranno questo proxy API con due parametri di query, un codice postale e un ID paese:

$ curl "http://{myorg}-test.apigee.net/policy-mashup-cookbook?country=us&postalcode=08008"

La risposta è un oggetto JSON che include la posizione geocodificata (latitudine/longitudine) per il centro dell'area del codice postale fornita combinata con l'elevazione in quella posizione geocodificata.

{  
   "ElevationResponse":{  
      "status":"OK",
      "result":{  
         "location":{  
            "lat":"39.7500713",
            "lng":"-74.1357407"
         },
         "elevation":"0.5045232",
         "resolution":"76.3516159"
      }
   }
}

Prima di iniziare

Se vuoi leggere una breve panoramica del pattern di composizione dei criteri, consulta "Il pattern di composizione dei criteri" nei pattern delle istruzioni su proxy API.

Prima di esplorare l'esempio di questo libro di ricette, dovresti anche acquisire familiarità con questi concetti fondamentali:

  • Cosa sono i criteri e come collegarli ai proxy. Per un'introduzione alle norme, consulta la sezione Che cosa sono i criteri?.
  • La struttura di un flusso proxy API, come spiegato in Configurare i flussi. I flussi consentono di specificare la sequenza in cui i criteri vengono eseguiti da un proxy API. In questo esempio, vengono creati e aggiunti diversi criteri al flusso del proxy API.
  • Modalità di organizzazione di un progetto proxy API nel file system, come spiegato nella documentazione di configurazione del proxy API. Questo argomento del libro di ricette dimostra lo sviluppo locale (basato su file system) anziché lo sviluppo basato su cloud in cui potresti utilizzare l'interfaccia utente di gestione per sviluppare il proxy API.
  • Utilizzo della convalida delle chiavi API. Questa è la forma più semplice di sicurezza basata su app che puoi configurare per un'API. Per maggiori informazioni, consulta la sezione Chiavi API. Puoi anche seguire il tutorial Proteggere un'API richiedendo chiavi API.
  • Conoscenza pratica del linguaggio XML. In questo esempio, creiamo il proxy API e i relativi criteri con file XML che risiedono nel file system.

Se hai scaricato il codice di esempio, puoi individuare tutti i file discussi in questo argomento nella cartella di esempio mashup-policy-cookbook. Le sezioni seguenti trattano il codice di esempio in dettaglio.

Seguire il flusso

Prima di passare ai criteri, diamo un'occhiata al flusso principale del nostro proxy API di esempio. Il flusso XML di seguito, mostrato di seguito, ci fornisce molte informazioni su questo proxy, sui criteri che utilizza e su dove vengono chiamati.

Nel download di esempio, puoi trovare questo XML nel file doc-samples/policy-mashup-cookbook/apiproxy/proxies/default.xml.

<ProxyEndpoint name="default">
  <Flows>
    <Flow name="default">
      <Request>
            <!-- Generate request message for the Google Geocoding API -->
            <Step><Name>GenerateGeocodingRequest</Name></Step>
            <!-- Call the Google Geocoding API -->
            <Step><Name>ExecuteGeocodingRequest</Name></Step>
            <!-- Parse the response and set variables -->
            <Step><Name>ParseGeocodingResponse</Name></Step>
            <!-- Generate request message for the Google Elevation API -->
            <Step><Name>AssignElevationParameters</Name></Step>
      </Request>
      <Response>
            <!-- Parse the response message from the Elevation API -->
            <Step><Name>ParseElevationResponse</Name></Step>
            <!-- Generate the final JSON-formatted response with JavaScript -->
            <Step><Name>GenerateResponse</Name></Step>
      </Response>
    </Flow>
  </Flows>

  <HTTPProxyConnection>
    <!-- Add a base path to the ProxyEndpoint for URI pattern matching-->
    <BasePath>/policy-mashup-cookbook</BasePath>
    <!-- Listen on both HTTP and HTTPS endpoints -->
    <VirtualHost>default</VirtualHost>
    <VirtualHost>secure</VirtualHost>
  </HTTPProxyConnection>
  <RouteRule name="default">
    <!-- Connect ProxyEndpoint to named TargetEndpoint under /targets -->
    <TargetEndpoint>default</TargetEndpoint>
  </RouteRule>
</ProxyEndpoint>

Ecco un riepilogo degli elementi del flusso.

  • <Request>: l'elemento <Request> è composto da diversi elementi <Step>. Ogni passaggio chiama uno dei criteri che creeremo nel resto di questo argomento. Questi criteri riguardano la creazione, l'invio e l'analisi della risposta di un messaggio di richiesta. Alla fine di questo argomento, capirai il ruolo di ciascuno di questi criteri.
  • <Response>: l'elemento <Response> include anche <Steps>. Questi passaggi includono anche le norme sulle chiamate che sono responsabili dell'elaborazione della risposta finale dall'endpoint di destinazione (l'API Google Elevation).
  • <HttpProxyConnection>: questo elemento specifica i dettagli su come le app si connetteranno a questo proxy API, incluso <BasePath>, che specifica come verrà chiamata questa API.
  • <RouteRule>: questo elemento specifica cosa succede subito dopo l'elaborazione dei messaggi di richiesta in entrata. In questo caso viene chiamato TargetEndpoint. Approfondiremo questo passaggio importante più avanti in questo argomento.

Creazione dei criteri

Le sezioni seguenti illustrano ciascuna delle norme che costituiscono questo esempio di composizione dei criteri.

Crea il primo criterio di AssegnaMessage

Il primo criterio AssignMessage, elencato di seguito, crea un messaggio di richiesta che verrà inviato al servizio Google Geocoding.

Iniziamo con il codice delle norme, quindi ne spiegheremo gli elementi in modo più dettagliato. Nel download di esempio, puoi trovare questo XML nel file doc-samples/policy-mashup-cookbook/apiproxy/policies/GenerateGeocodingRequest.xml.

<AssignMessage name="GenerateGeocodingRequest">
  <AssignTo createNew="true" type="request">GeocodingRequest</AssignTo>
  <Set>
    <QueryParams>
      <QueryParam name="address">{request.queryparam.postalcode}</QueryParam>
      <QueryParam name="region">{request.queryparam.country}</QueryParam>
      <QueryParam name="sensor">false</QueryParam>
    </QueryParams>
    <Verb>GET</Verb>
  </Set>
  <!-- Set variables for use in the final response -->
  <AssignVariable>
    <Name>PostalCode</Name>
    <Ref>request.queryparam.postalcode</Ref>
  </AssignVariable>
  <AssignVariable>
    <Name>Country</Name>
    <Ref>request.queryparam.country</Ref>
  </AssignVariable>
</AssignMessage>

Di seguito è riportata una breve descrizione degli elementi di queste norme. Per saperne di più su questo criterio, consulta l'articolo Assegnare criteri relativi ai messaggi.

  • <AssignMessage name>: assegna un nome al criterio. Il nome viene utilizzato quando viene fatto riferimento al criterio in un flusso.
  • <AssignTo>: crea una variabile con nome denominata GeocodingRequest. Questa variabile incapsula l'oggetto della richiesta che verrà inviato al backend dal criterio ServiceCallout.
  • <QueryParams> - Imposta i parametri di query necessari per la chiamata API di backend. In questo caso, l'API Geocoding deve conoscere la località, espressa con un codice postale, e un ID paese. L'utente dell'app fornisce queste informazioni, che ci limitiamo a estrarre qui. Il parametro sensor è obbligatorio dall'API ed è true o false; in questo caso lo impostiamo come hardcoded su false.
  • <Verb> - In questo caso, stiamo effettuando una semplice richiesta GET all'API.
  • <AssignVariable>: queste variabili memorizzano i valori che passiamo all'API. In questo esempio, si accederà alle variabili in un secondo momento nella risposta restituita al client.

Invia la richiesta con ServiceCallout

Il passaggio successivo nella sequenza di composizione delle norme consiste nel creare una norma ServiceCallout. Il criterio ServiceCallout, elencato di seguito, invia l'oggetto di richiesta che abbiamo creato nel precedente criterio di AssegnaMessage al servizio Google Geocoding e salva il risultato in una variabile denominata GeocodingResponse.

Come prima, diamo un'occhiata al codice. Segue una spiegazione dettagliata. Per saperne di più su queste norme, consulta le norme relative ai callout di servizio. Nel download di esempio, puoi trovare questo XML nel file doc-samples/policy-mashup-cookbook/apiproxy/policies/ExecuteGeocodingRequest.xml.

<ServiceCallout name="ExecuteGeocodingRequest">
  <Request variable="GeocodingRequest"/>
  <Response>GeocodingResponse</Response>
  <HTTPTargetConnection>
    <URL>http://maps.googleapis.com/maps/api/geocode/json</URL>
  </HTTPTargetConnection>
</ServiceCallout>

Di seguito è riportata una breve descrizione degli elementi di queste norme.

  • <ServiceCallout>: come nella norma precedente, anche questa ha un nome.
  • <Variabile di richiesta>: questa è la variabile creata nel criterio di AssegnaMessage. Incapsula la richiesta inviata all'API di backend.
  • <Response> - Questo elemento denomina una variabile in cui viene archiviata la risposta. Come puoi notare, il criterio ExtractVariables accederà a questa variabile in un secondo momento.
  • <HTTPTargetConnection>: specifica l'URL di destinazione dell'API di backend. In questo caso, specifichiamo che l'API restituisce una risposta JSON.

Ora abbiamo due criteri: uno che specifica le informazioni della richiesta necessarie per utilizzare l'API di backend (l'API Geocoding di Google) e il secondo che invia effettivamente la richiesta all'API di backend. Ora ci occuperemo della risposta.

Analizza la risposta con ExtractVariables

Il criterio ExtractVariables offre un meccanismo semplice per analizzare i contenuti del messaggio di risposta ottenuto da un criterio ServiceCallout. Il parametro ExtractVariables può essere utilizzato per analizzare JSON o XML oppure per estrarre contenuti da percorsi URI, intestazioni HTTP, parametri di query e parametri modulo.

Di seguito è riportato un elenco della norma ExtractVariables. Per saperne di più su questo criterio, consulta la pagina relativa al criterio Estrai variabili. Nel download di esempio, puoi trovare questo XML nel file doc-samples/policy-mashup-cookbook/apiproxy/policies/ParseGeocodingResponse.xml.

<ExtractVariables name="ParseGeocodingResponse">
  <Source>GeocodingResponse</Source>
  <VariablePrefix>geocoderesponse</VariablePrefix>
  <JSONPayload>
    <Variable name="latitude">
       <JSONPath>$.results[0].geometry.location.lat</JSONPath>
    </Variable>
    <Variable name="longitude">
       <JSONPath>$.results[0].geometry.location.lng</JSONPath>
    </Variable>
  </JSONPayload>
</ExtractVariables>

Gli elementi chiave della norma ExtractVariable sono:

  • <ExtractVariables name> - Anche in questo caso, il nome del criterio viene utilizzato per fare riferimento al criterio quando viene utilizzato in un flusso.
  • <Source> - Specifica la variabile di risposta creata nelle norme relative ai callout di servizio. Questa è la variabile da cui il criterio estrae i dati.
  • <VariablePrefix>: il prefisso della variabile specifica uno spazio dei nomi per altre variabili create in questo criterio. Il prefisso può essere qualsiasi nome, ad eccezione dei nomi riservati definiti dalle variabili predefinite di Edge.
  • <JSONPayload>: questo elemento recupera i dati della risposta che ci interessano e li inserisce in variabili con nome. In effetti, l'API Geocoding restituisce molte più informazioni rispetto a latitudine e longitudine. Tuttavia, questi sono gli unici valori necessari per questo campione. Puoi vedere un rendering completo del JSON restituito dall'API Geocoding nella documentazione dell'API. I valori di geometria.location.lat e creative.location.lng sono semplicemente due dei numerosi campi nell'oggetto JSON restituito.

Potrebbe non essere ovvio, ma è importante vedere che ExtractVariables genera due variabili i cui nomi comprendono il prefisso di variabile (Geographicresponse) e i nomi effettivi delle variabili specificati nel criterio. Queste variabili sono memorizzate nel proxy API e saranno disponibili per altri criteri all'interno del flusso del proxy, come vedrai. Le variabili sono:

  • geocoderesponse.latitude
  • geocoderesponse.longitude

La maggior parte del lavoro è ora completata. Abbiamo creato un insieme di tre criteri che formano una richiesta, chiamano un'API di backend e analizzano i dati JSON restituiti. Nei passaggi finali, inseriremo i dati di questa parte del flusso in un altro criterio di AssegnaMessage, chiameremo la seconda API di backend (API Google Elevation) e restituiremo i dati combinati allo sviluppatore dell'app.

Genera la seconda richiesta con AttributionMessage

Il seguente criterio di AssegnaMessage utilizza le variabili restituite dal primo backend (Google Geocoding) che abbiamo archiviato e le inserisce in una richiesta destinata alla seconda API (Google Elevation). Come indicato in precedenza, queste variabili sono Geographicresponse.Latitudine e Geographicresponse.longitudine.

Nel download di esempio, puoi trovare questo XML nel file doc-samples/policy-mashup-cookbook/apiproxy/policies/AssignElevationParameters.xml.

<AssignMessage name="AssignElevationParameters">
<Remove>
    <QueryParams>
      <QueryParam name="country"/>
      <QueryParam name="postalcode"/>
    </QueryParams>
  </Remove>
  <Set>
    <QueryParams>
      <QueryParam name="locations">{geocoderesponse.latitude},{geocoderesponse.longitude}</QueryParam>
      <QueryParam name="sensor">false</QueryParam>
    </QueryParams>
  </Set>
</AssignMessage>

Se esamini l'API Google Elevation, noterai che prende due parametri di query. Il primo si chiama locations e il suo valore è la latitudine e la longitudine (valori separati da virgola). L'altro parametro è sensor, obbligatorio e deve essere true o false. La cosa più importante da notare a questo punto è che il messaggio di richiesta creato qui non richiede un ServiceCallout. A questo punto non è necessario chiamare la seconda API da un ServiceCallout perché possiamo chiamare l'API di backend da TargetEndpoint del proxy. Se ci pensate, abbiamo tutti i dati che ci servono per chiamare l'API Google Elevations. Il messaggio di richiesta generato in questo passaggio non richiede un ServiceCallout, in quanto la richiesta generata per la pipeline di richiesta principale verrà inoltrata semplicemente da ProxyEndpoint a TargetEndpoint, seguendo la RouteRule configurata per questo proxy API. TargetEndpoint gestisce la connessione con l'API remota. Ricorda che l'URL per l'API elevazione è definito nella HTTPConnection per TargetEndpoint. Documentazione dell'API Elevation per saperne di più. I QueryParams che abbiamo archiviato in precedenza, country e postalcode, non sono più necessari, quindi li rimuoviamo qui.

Breve pausa: torna al flusso

A questo punto, vi chiederete perché non stiamo creando un'altra norma sui callout di servizio. Dopo tutto, abbiamo creato un altro messaggio. In che modo il messaggio viene inviato al target, l'API Google Elevation? La risposta si trova nell'elemento <RouteRule> del flusso. <RouteRule> specifica cosa fare con gli eventuali messaggi di richiesta rimanenti dopo l'esecuzione della parte <Request> del flusso. TargetEndpoint specificato da <RouteRule> indica al proxy API di consegnare il messaggio a http://maps.googleapis.com/maps/api/elevation/xml.

Se hai scaricato il proxy API di esempio, puoi trovare il valore XML TargetProxy nel file doc-samples/policy-mashup-cookbook/apiproxy/targets/default.xml.

<TargetEndpoint name="default">
  <HTTPTargetConnection>
    <!-- This is where we define the target. For this sample we just use a simple URL. -->
    <URL>http://maps.googleapis.com/maps/api/elevation/xml</URL>
  </HTTPTargetConnection>
</TargetEndpoint>

Ora dobbiamo solo elaborare la risposta dall'API Google Elevation, ed è fatta.

Converti la risposta da XML a JSON

In questo esempio, la risposta dell'API Google Elevation viene restituita in formato XML. Per il "merito extra", aggiungiamo un altro criterio al nostro elemento composito per trasformare la risposta da XML a JSON.

Questo esempio utilizza il criterio JavaScript denominato GeneraResponse, con un file di risorse contenente il codice JavaScript, per eseguire la conversione. Di seguito è riportata la definizione del criterio GeneraResponse:

<Javascript name="GenerateResponse" timeout="10000">
  <ResourceURL>jsc://GenerateResponse.js</ResourceURL>
</Javascript>

Il file di risorse generateResponse.js include il codice JavaScript utilizzato per eseguire la conversione. Puoi visualizzare il codice nel file doc-samples/policy-mashup-cookbook/apiproxy/resources/JSC/GenerateResponse.js.

Apigee fornisce anche un criterio pronto all'uso, XMLToJSON, per convertire i file XML in JSON. Puoi modificare ProxyEndpoint in modo che utilizzi il criterio xmltojson mostrato di seguito.

<XMLToJSON name="xmltojson">
  <Options>
  </Options>
  <OutputVariable>response</OutputVariable>
  <Source>response</Source>
</XMLToJSON>

Test dell'esempio

Se non lo hai già fatto, prova a scaricare, eseguire il deployment ed eseguire l'esempio policy-mashup-cookbook, che puoi trovare nella cartella documenti-esempi nel repository di esempi Apigee Edge GitHub. Segui le istruzioni nel file README nella cartella policy-mashup-cookbook. In alternativa, segui le brevi istruzioni riportate qui: Utilizzo dei proxy API di esempio.

Riassumendo, puoi chiamare l'API composita come indicato di seguito. Sostituisci {myorg} con il nome della tua organizzazione:

$ curl "http://{myorg}-test.apigee.net/policy-mashup-cookbook?country=us&postalcode=08008"

La risposta include la posizione geocodificata per il centro del codice postale fornito dall'utente finale dell'app, combinata con l'altitudine di quella posizione geocodificata. I dati sono stati recuperati da due API di backend, combinati con i criteri collegati al proxy API e restituiti al client in un'unica risposta.

{  
   "country":"us",
   "postalcode":"08008",
   "elevation":{  
      "meters":0.5045232,
      "feet":1.6552599030345978
   },
   "location":{  
      "latitude":39.75007129999999,
      "longitude":-74.1357407
   }
}

Riepilogo

In questo argomento del libro di ricette viene spiegato come utilizzare il pattern di composizione dei criteri per creare un mashup di dati da più origini backend. La composizione dei criteri è un pattern comune utilizzato nello sviluppo di proxy API per aggiungere funzionalità delle creatività all'API.