Best practice per la progettazione e lo sviluppo di proxy API con Apigee

Questa pagina si applica ad Apigee e Apigee hybrid.

Visualizza la documentazione di Apigee Edge.

Questo documento fornisce una serie di best practice per lo sviluppo di proxy API con Apigee.

Gli argomenti trattati includono progettazione, codifica, utilizzo dei criteri, monitoraggio e debug. Le informazioni sono state raccolte dall'esperienza degli sviluppatori che lavorano con Apigee per implementare programmi API di successo. Questo documento è in continuo aggiornamento e verrà aggiornato di volta in volta.

Oltre alle linee guida riportate qui, potresti trovare utile anche la pagina Introduzione agli antipattern.

Standard di sviluppo

Commenti e documentazione

  • Fornisci commenti in linea nelle configurazioni ProxyEndpoint e TargetEndpoint. I commenti migliorano la leggibilità di un flusso, soprattutto se i nomi dei file dei criteri non sono sufficientemente descrittivi per esprimere la funzionalità di base del flusso.
  • Rendi utili i commenti. Evita commenti scontati.
  • Utilizza rientri, spaziature, allineamento verticale e così via coerenti.

Codifica in stile framework

La codifica in stile framework prevede l'archiviazione delle risorse proxy API nel tuo sistema di controllo della versione per il riutilizzo negli ambienti di sviluppo locale. Ad esempio, per riutilizzare un criterio, memorizzalo nel controllo del codice sorgente in modo che gli sviluppatori possano sincronizzarsi e utilizzarlo nei propri ambienti di sviluppo proxy.

  • Per attivare il principio DRY (don't repeat yourself, non ripeterti), ove possibile, le configurazioni dei criteri e gli script devono implementare funzioni specializzate e riutilizzabili. Ad esempio, un criterio dedicato per estrarre parametri di ricerca dai messaggi di richiesta potrebbe essere chiamato ExtractVariables.ExtractRequestParameters.
  • Elimina i criteri e le risorse inutilizzati (JavaScript, Java, XSLT e così via) dai proxy API, in particolare le risorse di grandi dimensioni che potrebbero rallentare le procedure di importazione e di deployment.

Convenzioni di denominazione

  • L'attributo name del criterio e il nome del file del criterio XML devono essere identici.
  • L'attributo name del criterio Script e del criterio Criterio callout del servizio e il nome del file della risorsa devono essere identici.
  • DisplayName deve descrivere con precisione la funzione del criterio a qualcuno che non ha mai lavorato con quel proxy API prima d'ora.
  • Assegna un nome ai criteri in base alla loro funzione. Apigee consiglia di stabilire una convenzione di denominazione coerente per i criteri. Ad esempio, utilizza prefissi brevi seguiti da una sequenza di parole descrittive separate da trattini. Ad esempio, AM-xxx per il criterio Assegna messaggio. Vedi anche lo strumento apigeelint.
  • Utilizza le estensioni appropriate per i file di risorse, .js per JavaScript, .py per Python e .jar per i file JAR Java.
  • I nomi delle variabili devono essere coerenti. Se scegli uno stile, ad esempio camelCase o under_score, utilizzalo in tutto il proxy API.
  • Se possibile, utilizza i prefissi delle variabili per organizzare le variabili in base alla loro finalità, ad esempio Consumer.username e Consumer.password.

Sviluppo di proxy API

Considerazioni iniziali sul design

  • Per indicazioni sulla progettazione di API RESTful, scarica l'ebook Web API Design: The Missing Link.
  • Sfrutta le norme e le funzionalità di Apigee, ove possibile, per creare proxy API. Evita di codificare tutta la logica del proxy nelle risorse JavaScript, Java o Python.
  • Costruisci i flussi in modo organizzato. È preferibile utilizzare più flussi, ciascuno con una singola condizione, anziché più allegati condizionali allo stesso PreFlow e Postflow.
  • Come "piano di riserva", crea un proxy API predefinito con un BasePath di ProxyEndpoint di /. Questo può essere utilizzato per reindirizzare le richieste dell'API di base a un sito per sviluppatori, per restituire una risposta personalizzata o per eseguire un'altra azione più utile rispetto al valore predefinito messaging.adaptors.http.flow.ApplicationNotFound.
  • Per un rendimento ottimale, Apigee consiglia di utilizzare non più di 3000 percorsi base dell'proxy API per ambiente Apigee o gruppo di ambienti. Il superamento di questo valore consigliato può comportare un aumento della latenza per tutti i deployment di proxy API nuovi ed esistenti.
  • Utilizza le risorse TargetServer per disaccoppiare le configurazioni di TargetEndpoint dagli URL specifici, supportando la promozione tra gli ambienti.
    Consulta Bilanciamento del carico tra server di backend.
  • Se hai più RouteRule, creane una come "predefinita", ovvero come RouteRule senza condizioni. Assicurati che la regola di routing predefinita sia definita per ultima nell'elenco dei percorsi condizionali. Le regole Route vengono valutate dall'alto verso il basso in ProxyEndpoint. Consulta il riferimento per la configurazione dei proxy API.
  • Dimensioni del bundle proxy API: i bundle proxy API non possono avere dimensioni maggiori di 15 MB.
  • Controllo delle versioni delle API: per le opinioni e i consigli di Apigee sul controllo delle versioni delle API, consulta Controllo delle versioni nell'ebook Web API Design: The Missing Link.

Attivazione di CORS

Prima di pubblicare le API, devi aggiungere il criterio CORS al preflusso della richiesta di ProxyEndpoint per supportare le richieste cross-origin lato client.

CORS (Cross-Origin Resource Sharing) è un meccanismo standard che consente alle chiamate XMLHttpRequest (XHR) di JavaScript eseguite in una pagina web di interagire con le risorse di domini diversi da quello di origine. CORS è una soluzione comunemente implementata per i criteri della stessa origine applicati da tutti i browser. Ad esempio, se effettui una chiamata XHR all'API Twitter dal codice JavaScript eseguito nel browser, la chiamata non andrà a buon fine. Questo perché il dominio che pubblica la pagina nel browser non è lo stesso del dominio che pubblica l'API Twitter. CORS fornisce una soluzione a questo problema consentendo ai server di attivare la condivisione delle risorse tra origini se vogliono fornire questa funzionalità.

Per informazioni su come attivare CORS sui proxy API prima di pubblicare le API, consulta Aggiunta del supporto CORS a un proxy API.

Dimensioni del payload del messaggio

Per evitare problemi di memoria in Apigee, le dimensioni del payload del messaggio sono limitate a 10 MB. Se si superano queste dimensioni, viene generato un errore protocol.http.TooBigBody.

Questo problema è trattato anche in Errore durante la richiesta/il ritorno di un payload di grandi dimensioni con il proxy Apigee.

Di seguito sono riportate le strategie consigliate per gestire messaggi di grandi dimensioni in Apigee:

Gestione degli errori

  • Utilizza FaultRules per gestire tutta la gestione degli errori. I criteri RaiseFault vengono utilizzati per interrompere il flusso di messaggi e inviare l'elaborazione al flusso FaultRules.
  • All'interno del flusso FaultRules, utilizza un criterio AssignMessage per creare la risposta all'errore, non un criterio RaiseFault. Esegui in modo condizionale i criteri AssignMessage in base al tipo di errore che si verifica.
  • Include sempre un gestore degli errori "generico" predefinito in modo che gli errori generati dal sistema possano essere mappati ai formati di risposta agli errori definiti dal cliente.
  • Se possibile, assicurati sempre che le risposte agli errori corrispondano a eventuali formati standard disponibili nella tua azienda o nel tuo progetto.
  • Utilizza messaggi di errore significativi e leggibili che suggeriscano una soluzione alla condizione di errore.

Consulta la sezione Gestione degli errori.

Persistenza

Mappe chiave/valore

  • Utilizza le mappe chiave/valore solo per set di dati limitati. Non sono progettati per essere un archivio di dati a lungo termine.
  • Tieni conto del rendimento quando utilizzi le mappe chiave/valore, poiché queste informazioni vengono memorizzate nel database Cassandra.

Consulta le norme relative a KeyValueMapOperations.

Memorizzazione nella cache delle risposte

  • Non compilare la cache della risposta se la risposta non è corretta o se la richiesta non è GET. Le operazioni di creazione, aggiornamento ed eliminazione non devono essere memorizzate nella cache. <SkipCachePopulation>response.status.code != 200 or request.verb != "GET"</SkipCachePopulation>
  • Compila la cache con un unico tipo di contenuti coerente (ad esempio XML o JSON). Dopo aver recuperato una voce responseCache, convertila nel tipo di contenuto necessario con JSONtoXML o XMLToJSON. In questo modo eviterai di memorizzare dati doppi, tripli o più.
  • Assicurati che la chiave della cache sia sufficiente per soddisfare il requisito di memorizzazione nella cache. In molti casi, il valore request.querystring può essere utilizzato come identificatore univoco.
  • Non includere la chiave API (client_id) nella chiave cache, a meno che non sia obbligatoria. Molto spesso, le API protette solo da una chiave restituiscono gli stessi dati a tutti i client per una determinata richiesta. Non è efficiente memorizzare lo stesso valore per un numero di voci in base alla chiave API.
  • Imposta intervalli di scadenza della cache appropriati per evitare letture sporche.
  • Se possibile, cerca di eseguire il criterio di cache delle risposte che compila la cache nel post-flusso della risposta di ProxyEndpoint il più tardi possibile. In altre parole, eseguila dopo i passaggi di traduzione e mediazione, inclusa la mediazione basata su JavaScript e la conversione tra JSON e XML. Memorizzando nella cache i dati mediati, eviti il costo in termini di prestazioni dell'esecuzione del passaggio di mediazione ogni volta che recuperi i dati memorizzati nella cache.

    Tieni presente che potresti preferire memorizzare nella cache i dati non mediati se la mediazione genera una risposta diversa da una richiesta all'altra.

  • Il criterio della cache della risposta per cercare la voce della cache deve verificarsi nel PreFlow della richiesta ProxyEndpoint. Evita di implementare troppa logica, oltre alla generazione della chiave della cache, prima di restituire una voce della cache. In caso contrario, i vantaggi della memorizzazione nella cache vengono ridotti al minimo.
  • In generale, devi sempre mantenere la ricerca nella cache della risposta il più vicino possibile alla richiesta del client. Al contrario, devi mantenere la popolazione della cache delle risposte il più vicino possibile alla risposta del cliente.
  • Quando utilizzi più criteri di cache delle risposte diversi in un proxy, segui queste linee guida per garantire un comportamento distinto per ciascuno:
    • Esegui ogni criterio in base a condizioni mutuamente esclusive. In questo modo, verrà eseguito solo uno dei più criteri di cache delle risposte.
    • Definisci risorse della cache diverse per ogni criterio della cache delle risposte. Specifica la risorsa cache nell'elemento <CacheResource> del criterio.

Consulta le norme relative a ResponseCache.

Norme e codice personalizzato

Criterio o codice personalizzato?

  • Utilizza innanzitutto i criteri integrati (se possibile). I criteri Apigee sono rafforzati, ottimizzati e supportati. Ad esempio, utilizza i criteri standard AssignMessage e ExtractVariables anziché JavaScript (se possibile) per creare payload, estrarre informazioni dai payload (XPath, JSONPath) e così via.
  • È preferibile utilizzare JavaScript rispetto a Python e Java. Tuttavia, se il rendimento è il requisito principale, è preferibile utilizzare Java anziché JavaScript.

JavaScript

  • Utilizza JavaScript se è più intuitivo dei criteri Apigee (ad esempio, quando imposti target.url per molte combinazioni diverse di URI).
  • Analisi complessa del payload, ad esempio l'iterazione di un oggetto JSON e la codifica/decodifica Base64.
  • Le norme relative a JavaScript hanno un limite di tempo, pertanto i loop infiniti sono bloccati.
  • Utilizza sempre i passaggi JavaScript e inserisci i file nella cartella delle risorse jsc. Il tipo di norma JavaScript precompila il codice al momento del deployment.

Java

  • Utilizza Java se il rendimento ha la massima priorità o se la logica non può essere implementata in JavaScript.
  • Includi i file di origine Java nel monitoraggio del codice sorgente.

Per informazioni sull'utilizzo di Java nei proxy API, consulta il criterio JavaCallout.

Python

  • Non utilizzare Python, a meno che non sia assolutamente necessario. Gli script Python possono introdurre colli di bottiglia per le prestazioni per le esecuzioni semplici, in quanto vengono interpretati in fase di esecuzione.

Callout di script (Java, JavaScript, Python)

  • Utilizza un blocco try/catch globale o equivalente.
  • Lanciati eccezioni significative e gestiscile correttamente per utilizzarle nelle risposte agli errori.
  • Lancia ed esegui il rilevamento delle eccezioni in anticipo. Non utilizzare try/catch globale per gestire tutte le eccezioni.
  • Esegui controlli su valori null e non definiti, se necessario. Un esempio di quando eseguire questa operazione è quando recupero le variabili di flusso facoltative.
  • Evita di effettuare richieste HTTP/S all'interno di un callout di script. Utilizza invece il criterio ServiceCallout, in quanto gestisce le connessioni in modo corretto.

JavaScript

  • JavaScript sulla piattaforma API supporta XML tramite E4X.

Consulta Modello oggetto JavaScript.

Java

  • Quando accedi ai payload dei messaggi, prova a utilizzare context.getMessage() anziché context.getResponseMessage o context.getRequestMessage. In questo modo, il codice può recuperare il payload sia nei flussi di richiesta che di risposta.
  • Importa le librerie nell'organizzazione o nell'ambiente Apigee e non includerle nel file JAR. In questo modo si riducono le dimensioni del bundle e altri file JAR potranno accedere allo stesso repository della biblioteca.
  • Importa i file JAR utilizzando l'API delle risorse Apigee anziché includerli all'interno della cartella delle risorse proxy dell'API. In questo modo, i tempi di implementazione verranno ridotti e sarà possibile fare riferimento agli stessi file JAR da più proxy API. Un altro vantaggio è l'isolamento del caricatore di classi.
  • Non utilizzare Java per la gestione delle risorse (ad esempio, la creazione e la gestione di pool di thread).

Python

  • Lanciati eccezioni significative e gestiscile correttamente per utilizzarle nelle risposte agli errori di Apigee

Consulta le norme di PythonScript.

ServiceCallouts

  • Esistono molti casi d'uso validi per l'utilizzo della catena di proxy, in cui utilizzi un callout di servizio in un proxy API per chiamare un altro proxy API. Se utilizzi il concatenamento di proxy, assicurati di evitare loop infiniti di callout ricorsivi nello stesso proxy API.

    Se ti colleghi tra proxy che si trovano nella stessa organizzazione e nello stesso ambiente, consulta la sezione Collegare in serie i proxy API per saperne di più sull'implementazione di una connessione locale che eviti un ovvio aggravio della rete.

  • Crea un messaggio di richiesta ServiceCallout utilizzando il criterio AssignMessage e compila l'oggetto request in una variabile di messaggio. (Questa operazione include l'impostazione del payload, del percorso e del metodo della richiesta).
  • L'URL configurato all'interno del criterio richiede la specifica del protocollo, il che significa che la parte di protocollo dell'URL, ad esempio https://, non può essere specificata da una variabile. Inoltre, devi utilizzare variabili separate per la parte di dominio dell'URL e per il resto dell'URL. Ad esempio: https://example.com.
  • Memorizza l'oggetto di risposta per un ServiceCallout in una variabile di messaggio separata. Puoi quindi analizzare la variabile messaggio e mantenere invariato il payload del messaggio originale per l'utilizzo da parte di altri criteri.

Consulta le norme relative a ServiceCallout.

Accesso alle entità

Criteri di AccessEntity

  • Per un rendimento migliore, cerca le app per uuid anziché per nome.

Consulta le norme relative ad AccessEntity.

Logging

  • Utilizza un criterio syslog comune in tutti i bundle e nello stesso bundle. In questo modo, manterrai un formato di registrazione coerente.

Consulta le norme relative a MessageLogging.

Monitoraggio

I clienti cloud non sono tenuti a controllare i singoli componenti di Apigee (router, elaboratori di messaggi e così via). Il team Global Operations di Apigee monitora attentamente tutti i componenti, nonché i controlli di integrità delle API, in base alle richieste del cliente.

Apigee Analytics

Analytics può fornire il monitoraggio delle API non critiche perché vengono misurate le percentuali di errore.

Consulta le dashboard di Analytics.

Debug

Lo strumento di traccia nella UI di Apigee è utile per eseguire il debug dei problemi relativi alle API di runtime, durante lo sviluppo o il funzionamento in produzione di un'API.

Consulta Utilizzare lo strumento di debug.

Sicurezza

Logica personalizzata nei proxy API

Un requisito comune per la creazione di proxy API è includere una logica per l'elaborazione delle richieste e/o delle risposte. Sebbene molti requisiti possano essere soddisfatti da un insieme predefinito di passaggi/azioni/norme, come la verifica di un token, l'applicazione di una quota o la risposta con un oggetto memorizzato nella cache, spesso può essere necessario l'accesso alla programmabilità. Ad esempio, la ricerca di una posizione (endpoint) da una tabella di routing in base a una chiave trovata in una richiesta e l'applicazione dinamica di un endpoint di destinazione o di un metodo di autenticazione personalizzato/proprietario e così via.

Apigee offre a uno sviluppatore più opzioni per gestire questa logica personalizzata. Questo documento esamina queste opzioni e quando utilizzarle:

Norme Casi d'uso dei criteri
JavaScript e PythonScript

Quando utilizzarlo:

  • I criteri JavaScript e PythonScript sono equivalenti in termini di funzionalità. La familiarità di uno sviluppatore con un linguaggio è in genere la motivazione per scegliere uno rispetto all'altro.
  • I criteri JavaScript e PythonScript sono i più adatti per l'elaborazione di logica in linea non eccessivamente complessa e che non richiede l'uso di librerie di terze parti.
  • Questi criteri non hanno lo stesso rendimento del criterio JavaCallout.

Quando non utilizzarli:

  • API Gateway di Apigee non è un server di applicazioni (e non fornisce il runtime JavaScript completo come node.js). Se l'elaborazione del callout richiede sempre più di un secondo, è molto probabile che la logica non appartenga al gateway e debba invece far parte del servizio sottostante.

Best practice: Apigee consiglia JavaScript anziché PythonScript, poiché JavaScript offre un rendimento migliore.

JavaCallout

Quando utilizzarlo:

  • Le prestazioni dell'elaborazione della logica in linea sono fondamentali.
  • Le librerie Java esistenti forniscono gran parte della logica.

Quando non utilizzarli:

  • Il gateway API di Apigee non è un server di applicazioni e non è progettato per caricare framework come Spring, JEE e così via. Se in genere l'elaborazione del callout richiede più di un secondo, la logica può essere considerata funzionale (logica di business). Valuta la possibilità di esternalizzare come servizio.
  • Per proteggere l'API Gateway di Apigee da comportamenti illeciti, sono state applicate limitazioni al tipo di codice che può essere eseguito. Ad esempio, l'esecuzione del codice Java che tenta di accedere a determinate librerie di crittografia o al file system viene bloccata.
  • Le applicazioni Java, in particolare quelle che si basano su librerie di terze parti, possono includere molti (e grandi) file JAR. Ciò può rallentare il tempo di avvio dei gateway.
ExternalCallout

Quando utilizzarlo:

  • Ideale per esternalizzare la logica personalizzata e consentire alla logica personalizzata di accedere (e se necessario modificare) il contesto del messaggio.
  • I callout esterni implementano gRPC e potrebbero avere un rendimento migliore rispetto a un ServiceCallout.
  • Quando utilizzi Apigee o Apigee Hybrid su Google Cloud, valuta la possibilità di utilizzare Cloud Functions o Cloud Run per ospitare questa logica.
  • Come sostituto efficace della funzionalità Target ospitati in Apigee Edge.

Quando non in uso:

  • Per una logica leggera che può essere eseguita rapidamente in linea.
ServiceCallout

Quando utilizzarlo:

  • La logica complessa è meglio implementarla al di fuori del gateway. Questa logica può avere un proprio ciclo di vita (release e controllo delle versioni) e non influisce sul funzionamento del gateway.
  • Quando l'endpoint REST/SOAP/GraphQL esiste già o può essere facilmente implementato
  • Quando utilizzi Apigee o Apigee Hybrid su Google Cloud, valuta la possibilità di utilizzare Cloud Functions o Cloud Run per ospitare questa logica.
  • Come sostituto efficace della funzionalità Target ospitati in Apigee Edge.

Quando non in uso:

  • Per una logica leggera che può essere eseguita rapidamente, in linea
  • Il proxy API deve trasferire il contesto (ad esempio le variabili) o riceverlo dall'implementazione esterna

In sintesi:

  1. Se la logica è semplice o banale, utilizza JavaScript (preferibilmente) o PythonScript.
  2. Se la logica in linea richiede prestazioni migliori rispetto a JavaScript o PythonScript, utilizza JavaCallout.
  3. Se la logica deve essere esternata, utilizza ExternalCallout.
  4. Se hai già implementazioni esterne e/o gli sviluppatori hanno dimestichezza con REST, utilizza ServiceCallout.

La figura seguente illustra questa procedura: