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 un insieme di best practice per lo sviluppo di proxy API con Apigee.

Gli argomenti trattati qui includono progettazione, programmazione, utilizzo delle norme, monitoraggio e debug. Le informazioni sono state raccolte dall'esperienza degli sviluppatori che lavorano con Apigee per implementare programmi API efficaci. Questo documento è in continuo aggiornamento e verrà aggiornato di tanto in tanto.

Oltre alle linee guida riportate qui, potrebbe esserti utile anche l'articolo 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 quando i nomi dei file delle norme non sono sufficientemente descrittivi per esprimere la funzionalità sottostante del flusso.
  • Scrivere commenti utili. Evita commenti ovvi.
  • Utilizza rientri, spaziatura, allineamento verticale e così via coerenti.

Programmazione in stile framework

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

  • Per attivare DRY (Don't Repeat Yourself), ove possibile, le configurazioni dei criteri e gli script devono implementare funzioni specializzate e riutilizzabili. Ad esempio, un criterio dedicato per estrarre parametri di ricercay dai messaggi di richiesta potrebbe essere chiamato ExtractVariables.ExtractRequestParameters.
  • Esegui la pulizia di criteri e risorse inutilizzati (JavaScript, Java, XSLT) dai proxy API, in particolare le risorse di grandi dimensioni che potrebbero rallentare le procedure di importazione e deployment.

Convenzioni di denominazione

  • L'attributo name del criterio e il nome del file XML del criterio devono essere identici.
  • L'attributo name dei criteri Script e ServiceCallout e il nome del file di risorse devono essere identici.
  • DisplayName deve descrivere con precisione la funzione del criterio a una persona che non ha mai utilizzato prima questo proxy API.
  • Assegna un nome alle norme in base alla loro funzione. Apigee consiglia di stabilire una convenzione di denominazione coerente per le policy. Ad esempio, utilizza prefissi brevi seguiti da una sequenza di parole descrittive separate da trattini. Ad esempio, AM-xxx per il criterio AssignMessage. Vedi anche lo strumento apigeelint.
  • Utilizza le estensioni corrette 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 al loro scopo, ad esempio Consumer.username e Consumer.password.

Sviluppo di proxy API

Considerazioni iniziali sulla progettazione

  • Per indicazioni sulla progettazione di API RESTful, scarica l'ebook Web API Design: The Missing Link.
  • Sfrutta le funzionalità e le norme di Apigee ovunque 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, ognuno con una singola condizione, anziché più allegati condizionali allo stesso pre-flusso e post-flusso.
  • Come "failsafe", crea un proxy API predefinito con un BasePath ProxyEndpoint di /. Può essere utilizzato per reindirizzare le richieste API di base a un sito per sviluppatori, per restituire una risposta personalizzata o per eseguire un'altra azione più utile rispetto alla restituzione del valore predefinito messaging.adaptors.http.flow.ApplicationNotFound.
  • Per un rendimento ottimale, Apigee consiglia di utilizzare non più di 3000 basepath proxy API per ambiente Apigee o gruppo di ambienti. Il superamento di questo suggerimento può comportare un aumento della latenza per tutti i deployment di proxy API nuovi ed esistenti.
  • Utilizza le risorse TargetServer per disaccoppiare le configurazioni TargetEndpoint dagli URL concreti, 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 condizione. Assicurati che RouteRule predefinito sia definito per ultimo nell'elenco delle route condizionali. Le RouteRules 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 superare i 15 MB.
  • Controllo delle versioni delle API: per conoscere le opinioni e i consigli di Apigee sul controllo delle versioni delle API, consulta la sezione Controllo delle versioni dell'ebook Web API Design: The Missing Link.

Abilitazione di CORS

Prima di pubblicare le API, devi aggiungere le norme CORS al PreFlow della richiesta di ProxyEndpoint per supportare le richieste multiorigine lato client.

CORS (Cross-origin resource sharing) è un meccanismo standard che consente alle chiamate JavaScript XMLHttpRequest (XHR) eseguite in una pagina web di interagire con risorse di domini non 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 in esecuzione nel browser, la chiamata non andrà a buon fine. Questo perché il dominio che pubblica la pagina nel tuo browser non è lo stesso che pubblica l'API Twitter. CORS fornisce una soluzione a questo problema consentendo ai server di attivare la condivisione delle risorse tra origini.

Per informazioni sull'abilitazione di CORS sui proxy API prima della pubblicazione delle API, vedi Aggiunta del supporto CORS a un proxy API.

Dimensioni payload messaggio

La dimensione del payload del messaggio nei flussi di richiesta o risposta per Apigee è limitata per impostazione predefinita a 10 MB. Gli utenti che richiedono l'elaborazione di payload di grandi dimensioni possono configurare un limite più elevato utilizzando l'elemento <Properties> nelle configurazioni ProxyEndpoint o TargetEndpoint dei proxy API.

Per ulteriori informazioni sull'utilizzo di response.payload.parse.limit o delle proprietà request.payload.parse.limit per configurare una dimensione massima del payload fino a 30 MB per i flussi di richiesta o risposta, consulta il riferimento alla configurazione del proxy API.

Tieni presente che il superamento delle dimensioni specificate per il messaggio comporta un errore protocol.http.TooBigBody.

Considera le seguenti strategie consigliate per la gestione di messaggi di grandi dimensioni in Apigee:

  • Consigliamo vivamente di isolare i proxy API che gestiscono spesso payload di grandi dimensioni in un ambiente dedicato per evitare un potenziale scenario di "vicino rumoroso". Le risorse di CPU e memoria del sistema vengono consumate in quantità maggiori dai proxy che gestiscono payload di grandi dimensioni, soprattutto se utilizzati in combinazione con criteri che interagiscono con payload di grandi dimensioni.
  • Consigliamo inoltre di limitare l'utilizzo dei criteri per interagire con payload di grandi dimensioni. L'utilizzo di criteri per analizzare e copiare ripetutamente i payload di richieste o risposte può influire negativamente sulle prestazioni del sistema.
  • Le organizzazioni che gestiscono grandi volumi di richieste con payload elevati sono invitate a fornire indirizzi IP aggiuntivi per evitare l'esaurimento delle porte dovuto allo scaling orizzontale.
  • Considera le richieste e le risposte di streaming. Tieni presente che durante lo streaming, le norme non hanno più accesso al contenuto dei messaggi. Vedi Flussi di dati per richieste e risposte.
  • Se la tua organizzazione utilizza la fatturazione con pagamento a consumo, ti consigliamo di utilizzare i limiti configurabili per i payload di grandi dimensioni solo per i proxy API di cui è stato eseguito il deployment nell'ambiente Comprehensive.

Gestione dei guasti

  • 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 di errori "catch-all" predefinito in modo che gli errori generati dal sistema possano essere mappati nei formati di risposta agli errori definiti dal cliente.
  • Se possibile, fai in modo che le risposte agli errori corrispondano a tutti i 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 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 KeyValueMapOperations.

Memorizzazione nella cache delle risposte

  • Non compilare la cache delle risposte se la risposta non ha esito positivo o se la richiesta non è una GET. Le operazioni di creazione, aggiornamento ed eliminazione non devono essere memorizzate nella cache. <SkipCachePopulation>response.status.code != 200 or request.verb != "GET"</SkipCachePopulation>
  • Riempi 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 si eviterà di memorizzare dati doppi, tripli o superiori.
  • Assicurati che la chiave della cache sia sufficiente per il requisito di memorizzazione nella cache. In molti casi, l'request.querystring può essere utilizzato come identificatore univoco.
  • Non includere la chiave API (client_id) nella chiave della cache, a meno che non sia esplicitamente richiesta. 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 una serie di voci in base alla chiave API.
  • Imposta intervalli di scadenza della cache appropriati per evitare letture sporche.
  • Se possibile, cerca di fare in modo che il criterio di memorizzazione nella cache delle risposte che popola la cache venga eseguito nel PostFlow della risposta ProxyEndpoint il più tardi possibile. In altre parole, deve essere eseguito dopo i passaggi di traduzione e mediazione, inclusi la mediazione basata su JavaScript e la conversione tra JSON e XML. Memorizzando nella cache i dati di mediazione, 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 voler memorizzare nella cache i dati non mediati se la mediazione genera una risposta diversa da richiesta a richiesta.

  • Il criterio di cache della risposta per cercare la voce della cache deve essere applicato nel PreFlow della richiesta ProxyEndpoint. Evita di implementare troppa logica, a parte la 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 delle risposte 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 client.
  • Quando utilizzi più criteri di memorizzazione nella cache delle risposte diversi in un proxy, segui queste linee guida per garantire un comportamento discreto per ciascuno:
    • Esegui ogni norma in base a condizioni reciprocamente 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. Specifichi la risorsa cache nell'elemento <CacheResource> dei criteri.

Consulta le norme ResponseCache.

Norme e codice personalizzato

Norme o codice personalizzato?

  • Utilizza innanzitutto le norme integrate (se possibile). Le policy Apigee sono rafforzate, ottimizzate e supportate. Ad esempio, utilizza i criteri standard AssignMessage e ExtractVariables anziché JavaScript (quando possibile) per creare payload, estrarre informazioni dai payload (XPath, JSONPath) e così via.
  • JavaScript è preferito a Python e Java. Tuttavia, se le prestazioni sono 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 di URI diverse).
  • Analisi di payload complessi, ad esempio l'iterazione in un oggetto JSON e la codifica/decodifica Base64.
  • Le norme JavaScript hanno un limite di tempo, quindi i loop infiniti vengono bloccati.
  • Utilizza sempre i passaggi JavaScript e inserisci i file nella cartella delle risorse jsc. Il tipo JavaScript policy precompila il codice al momento del deployment.

Java

  • Utilizza Java se il rendimento è la priorità più alta o se la logica non può essere implementata in JavaScript.
  • Includi i file sorgente Java nel monitoraggio del codice sorgente.

Consulta il criterio JavaCallout per informazioni sull'utilizzo di Java nei proxy API.

Python

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

Callout script (Java, JavaScript, Python)

  • Utilizza un blocco try/catch globale o equivalente.
  • Genera eccezioni significative e gestiscile correttamente per utilizzarle nelle risposte agli errori.
  • Genera e rileva le eccezioni in anticipo. Non utilizzare il blocco try/catch globale per gestire tutte le eccezioni.
  • Esegui controlli null e undefined, se necessario. Un esempio di quando farlo è quando recuperi le variabili di flusso facoltative.
  • Evita di effettuare richieste HTTP/S all'interno di un callout dello script. Utilizza invece la norma ServiceCallout, in quanto gestisce le connessioni in modo controllato.

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 nei flussi di richiesta e 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 gli altri file JAR possono accedere allo stesso repository della libreria.
  • Importa i file JAR utilizzando l'API Apigee Resources anziché includerli nella cartella delle risorse del proxy API. In questo modo si riducono i tempi di deployment e si consente a più proxy API di fare riferimento agli stessi file JAR. 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

  • Genera eccezioni significative e gestiscile correttamente per l'utilizzo nelle risposte agli errori di Apigee

Consulta le norme PythonScript.

ServiceCallouts

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

    Se ti connetti tra proxy che si trovano nella stessa organizzazione e nello stesso ambiente, consulta Concatenare i proxy API per saperne di più sull'implementazione di una connessione locale che evita un sovraccarico di rete non necessario.

  • Crea un messaggio di richiesta ServiceCallout utilizzando il criterio AssignMessage e compila l'oggetto della richiesta in una variabile di messaggio. (Ciò 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 del 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. A questo punto puoi analizzare la variabile del messaggio e mantenere intatto il payload del messaggio originale per l'utilizzo da parte di altri criteri.

Consulta le norme relative alle estensioni di chiamata.

Accedere alle entità

Policy AccessEntity

  • Per prestazioni migliori, cerca le app per uuid anziché per nome.

Consulta le norme AccessEntity.

Logging

  • Utilizza una policy syslog comune in tutti i bundle e all'interno dello stesso bundle. In questo modo, il formato di logging sarà coerente.

Consulta le norme relative alla registrazione dei messaggi.

Monitoraggio

I clienti cloud non sono tenuti a controllare i singoli componenti di Apigee (router, processori 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 di controllo di integrità del cliente.

Apigee Analytics

Analytics può fornire un monitoraggio non critico delle API man mano che vengono misurate le percentuali di errore.

Consulta le dashboard di Analytics.

Debug

Lo strumento di tracciamento nella UI Apigee è utile per il debug dei problemi di runtime delle API durante lo sviluppo o l'operazione di produzione di un'API.

Vedi Utilizzo dello strumento di debug.

Sicurezza

Logica personalizzata nei proxy API

Un requisito comune durante la creazione di proxy API è includere una logica per l'elaborazione di richieste e/o risposte. Sebbene molti requisiti possano essere soddisfatti da un insieme predefinito di passaggi/azioni/norme, come la verifica di un token o l'applicazione di una quota o la risposta con un oggetto memorizzato nella cache, spesso è 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 diverse opzioni per gestire questa logica personalizzata. Questo documento esplorerà queste opzioni e quando utilizzare ciascuna:

Norme Casi d'uso delle policy
JavaScript e PythonScript

Quando utilizzarlo:

  • Le norme JavaScript e PythonScript sono equivalenti in termini di funzionalità. La familiarità di uno sviluppatore con una lingua è in genere la motivazione per sceglierne una rispetto a un'altra.
  • Le norme JavaScript e PythonScript sono più adatte per l'elaborazione della logica in linea che non è eccessivamente complessa e non richiede l'utilizzo di librerie di terze parti.
  • Questi criteri non sono performanti come il criterio JavaCallout.

Quando non utilizzarli:

  • Il gateway API di Apigee non è un server delle applicazioni (né fornisce l'intero runtime JavaScript come node.js). Se la callout impiega sempre più di un secondo per essere elaborata, è molto probabile che la logica non appartenga al gateway e debba invece far parte del servizio sottostante.

Best practice: Apigee consiglia JavaScript anziché PythonScript, in quanto JavaScript offre prestazioni migliori.

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 delle applicazioni e non è progettato per caricare framework come Spring, JEE e così via. Se il callout richiede in genere più di un secondo per l'elaborazione, la logica può essere considerata funzionale (logica di business). Considera l'esternalizzazione come servizio.
  • Per proteggere l'API Gateway Apigee da comportamenti illeciti, sono state imposte 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 file JAR (di grandi dimensioni). Questi possono rallentare il tempo di avvio dei gateway.
ExternalCallout

Quando utilizzarlo:

  • Ideale per esternalizzare la logica personalizzata e consentire a quest'ultima di accedere (e se necessario modificare) il contesto del messaggio.
  • I callout esterni implementano gRPC e potrebbero avere prestazioni migliori 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 sostituzione efficace della funzionalità Hosted Targets in Apigee Edge.

Quando non utilizzare:

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

Quando utilizzarlo:

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

Quando non utilizzare:

  • 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 inline richiede prestazioni migliori rispetto a JavaScript o PythonScript, utilizza JavaCallout.
  3. Se la logica deve essere esternalizzata, utilizza ExternalCallout.
  4. Se hai già implementazioni esterne e/o gli sviluppatori hanno familiarità con REST, utilizza ServiceCallout.

La figura seguente illustra questo processo: