Best practice per la progettazione e lo sviluppo di proxy API

Stai visualizzando la documentazione di Apigee Edge.
Consulta la documentazione di Apigee X.
info

Lo scopo di questo documento è fornire un insieme di standard e best practice per lo sviluppo con Apigee Edge. 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 di successo. Questo documento è in continuo aggiornamento e verrà aggiornato di tanto in tanto.

Oltre alle linee guida riportate qui, potresti trovare utile anche il post della community Apigee Edge Antipatterns.

Standard di sviluppo

Commenti e documentazione

  • Fornisci commenti incorporati 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.
  • Rendi utili i commenti. 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 dei proxy.

  • Per abilitare 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 i parametri di ricerca dai messaggi di richiesta potrebbe essere chiamato ExtractVariables.ExtractRequestParameters. Un criterio dedicato per inserire le intestazioni CORS potrebbe essere chiamato AssignMessage.SetCORSHeaders. Queste norme possono essere memorizzate nel sistema di controllo del codice sorgente e aggiunte a ogni proxy API che deve estrarre i parametri o impostare le intestazioni CORS, senza richiedere la creazione di configurazioni ridondanti (e quindi meno gestibili).
  • Esegui la pulizia di criteri e 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 deployment.

Convenzioni di denominazione

  • L'attributo Policy name e il nome del file di criteri XML 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 della policy a una persona che non ha mai utilizzato prima questo proxy API.
  • Assegna un nome alle policy 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 i criteri 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 organizzarle in base allo 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'e-book Web API Design: The Missing Link.
  • Sfrutta le funzionalità e i criteri di Apigee Edge ovunque possibile per creare proxy API. Evita di codificare tutta la logica del proxy nelle risorse JavaScript, Java o Python.
  • Crea flussi in modo organizzato. È preferibile utilizzare più flussi, ognuno con una singola condizione, anziché più allegati condizionali allo stesso PreFlow e Postflow.
  • 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 eseguire un'altra azione più utile rispetto alla restituzione del valore predefinito messaging.adaptors.http.flow.ApplicationNotFound.
  • Utilizza le risorse TargetServer per disaccoppiare le configurazioni TargetEndpoint dagli URL concreti, supportando la promozione tra gli ambienti.
    Consulta Bilanciamento del carico tra i server di backend.
  • Se hai più RouteRule, creane una come "predefinita", ovvero come RouteRule senza condizione. Assicurati che RouteRule predefinita sia definita per ultima nell'elenco delle route condizionali. RouteRules vengono valutate dall'alto verso il basso in ProxyEndpoint.
    Consulta il riferimento alla configurazione del proxy API.
  • Dimensioni del pacchetto proxy API: i pacchetti proxy API non possono superare i 15 MB. In Apigee Edge for Private Cloud, puoi modificare la limitazione delle dimensioni modificando la proprietà thrift_framed_transport_size_in_mb nelle seguenti posizioni: cassandra.yaml (in Cassandra) e conf/apigee/management-server/repository.properties.
  • 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 nell'e-book Web API Design: The Missing Link.

Abilitazione di CORS

Prima di pubblicare le API, devi abilitare CORS sui proxy API per supportare le richieste multiorigine lato client.

CORS (condivisione delle risorse multiorigine) è un meccanismo standard che consente alle chiamate XMLHttpRequest (XHR) JavaScript eseguite in una pagina web di interagire con risorse di domini multiorigine. CORS è una soluzione comunemente implementata per il criterio della stessa origine applicato 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 "attivarsi" se vogliono fornire la condivisione di risorse multiorigine.

Per informazioni sull'abilitazione di CORS sui proxy API prima di pubblicare le API, vedi Aggiunta del supporto CORS a un proxy API.

Dimensioni payload messaggio

Per evitare problemi di memoria in Edge, la dimensione del payload del messaggio è limitata a 10 MB. Il superamento di queste dimensioni comporta un errore protocol.http.TooBigBody.

Questo problema è trattato anche in questo post della community Apigee.

Di seguito sono riportate le strategie consigliate per la gestione di messaggi di grandi dimensioni in Edge:

  • Richieste e risposte di stream. Tieni presente che durante lo streaming, le policy non hanno più accesso al contenuto dei messaggi. Consulta Richieste e risposte di streaming.
  • In Edge for Private Cloud versione 4.15.07 e precedenti, modifica il file http.properties del processore di messaggi per aumentare il limite nel parametro HTTPResponse.body.buffer.limit. Assicurati di eseguire il test prima di eseguire il deployment della modifica in produzione.
  • In Edge for Private Cloud versione 4.16.01 e successive, le richieste con un payload devono includere l'intestazione Content-Length oppure, in caso di streaming, l'intestazione "Transfer-Encoding: chunked". Per un POST a un proxy API con un payload vuoto, devi passare una Content-Length pari a 0.
  • In Edge for Private Cloud versione 4.16.01 e successive, imposta le seguenti proprietà in /opt/apigee/router.properties o message-processor.properties per modificare i limiti. Per saperne di più, consulta Imposta il limite di dimensione dei messaggi sul router o sul processore di messaggi.

    Entrambe le proprietà hanno un valore predefinito di "10m" corrispondente a 10 MB:
    • conf_http_HTTPRequest.body.buffer.limit
    • conf_http_HTTPResponse.body.buffer.limit

Gestione dei guasti

  • Utilizza FaultRules per gestire tutta la gestione dei guasti. (Le policy RaiseFault vengono utilizzate per interrompere il flusso di messaggi e inviare l'elaborazione al flusso FaultRules.)
  • All'interno del flusso FaultRules, utilizza le policy AssignMessage per creare la risposta all'errore, non le policy RaiseFault. Esegui in modo condizionale le policy 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 ai 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.

Vedi Gestione dei guasti.

Per le best practice del settore, consulta Progettazione di risposte di errore RESTful.

Persistenza

Mappe di coppie 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 relative alle operazioni della mappa di coppie chiave-valore.

Memorizzazione nella cache delle risposte

  • Non compilare la cache delle risposte se la risposta non ha esito positivo 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 contenuto 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 evita di archiviare dati doppi, tripli o di più.
  • Assicurati che la chiave 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 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 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 la policy di memorizzazione nella cache delle risposte che popola la cache nel PostFlow della risposta ProxyEndpoint il più tardi possibile. In altre parole, esegui 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.

  • La policy di cache delle risposte per cercare la voce della cache deve essere eseguita nel PreFlow della richiesta ProxyEndpoint. Evita di implementare troppa logica, a parte la generazione della chiave 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 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 policy in base a condizioni reciprocamente esclusive. In questo modo, verrà eseguita solo una delle più politiche di memorizzazione nella cache delle risposte.
    • Definisci risorse della cache diverse per ogni policy di memorizzazione nella cache delle risposte. Specifica la risorsa cache nell'elemento <CacheResource> dei criteri.

Consulta le norme relative alla cache delle risposte.

Norme e codice personalizzato

Norme o codice personalizzato?

  • Utilizza innanzitutto le policy integrate (se possibile). Le policy Apigee sono protette, ottimizzate e supportate. Ad esempio, utilizza le policy standard AssignMessage ed ExtractVariables anziché JavaScript (se possibile) per creare payload, estrarre informazioni dai payload (XPath, JSONPath) e così via.
  • JavaScript è preferito a Python e Java. Tuttavia, se il rendimento è il requisito principale, Java deve essere utilizzato al posto di JavaScript.

JavaScript

  • Utilizza JavaScript se è più intuitivo delle policy 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.
  • La policy JavaScript ha 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 di policy JavaScript precompila il codice al momento del deployment.

Consulta Programmazione di proxy API con JavaScript.

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 Convertire la risposta in maiuscolo con un callout Java e Norme sui callout Java 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 esecuzioni semplici, in quanto vengono interpretati in fase di runtime.

Callout di 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 variabili di flusso facoltative.
  • Evita di effettuare richieste HTTP/S all'interno di un callout di script. Utilizza invece la policy Apigee ServiceCallout, in quanto gestisce le connessioni in modo appropriato.

JavaScript

  • JavaScript sulla piattaforma API supporta XML tramite E4X.

Consulta Modello a oggetti 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 nel flusso di richiesta che in quello di risposta.
  • Importa le librerie nell'organizzazione o nell'ambiente Apigee Edge 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).

Consulta Convertire la risposta in maiuscolo con un callout Java.

Python

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

Consulta le norme relative agli script Python.

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 callout ricorsivi "loop infinito" 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 eviti un sovraccarico di rete non necessario.

  • Crea un messaggio di richiesta ServiceCallout utilizzando la policy 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 della policy 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://{domain}/{path}
  • Memorizza l'oggetto di risposta per un ServiceCallout in una variabile di messaggio separata. Puoi quindi analizzare la variabile del messaggio e mantenere intatto il payload del messaggio originale per l'utilizzo da parte di altri criteri.

Consulta le Norme sui callout di servizio.

Accedere alle entità

AccessEntity Policy

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

Consulta le norme relative all'entità di accesso.

Logging

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

Consulta le norme MessageLogging.

Monitoraggio

I clienti cloud non sono tenuti a controllare i singoli componenti di Apigee Edge (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 dell'API, poiché vengono misurate le percentuali di errore.

Consulta Dashboard di Analytics.

Traccia

Lo strumento di tracciamento nell'UI di gestione API Edge è 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 Traccia.

Sicurezza