Questo documento illustra alcune tecniche che puoi utilizzare per migliorare le prestazioni della tua applicazione. In alcuni casi, vengono utilizzati esempi di altre API o API generiche per illustrare le idee presentate. Tuttavia, gli stessi concetti sono applicabili all'API Compute Engine.
Compressione con gzip
Un modo semplice e pratico per ridurre la larghezza di banda necessaria per ogni richiesta è attivare la compressione gzip. Sebbene questa richieda tempo di CPU aggiuntivo per decomprimere i risultati, il vantaggio a livello di costi di rete di solito la rende molto utile.
Per ricevere una risposta con codifica gzip, devi eseguire due operazioni: impostare un'intestazione Accept-Encoding
e modificare il tuo user agent in modo che contenga la stringa gzip
. Ecco un esempio di intestazioni HTTP formattate correttamente per attivare la compressione gzip:
Accept-Encoding: gzip User-Agent: my program (gzip)
Utilizzo di risorse parziali
Un altro modo per migliorare le prestazioni delle chiamate API è inviare e ricevere solo la parte di dati che ti interessa. In questo modo, l'applicazione evita di trasferire, analizzare e archiviare i campi non necessari, con una maggiore efficienza nell'utilizzo delle risorse, tra cui rete, CPU e memoria.
Esistono due tipi di richieste parziali:
- Risposta parziale: una richiesta in cui specifichi i campi da includere nella risposta (utilizza il parametro di richiesta
fields
). - Patch: una richiesta di aggiornamento in cui invii solo i campi che vuoi modificare (utilizza il verbo HTTP
PATCH
).
Maggiori dettagli su come inviare richieste parziali sono disponibili nelle sezioni seguenti.
Risposta parziale
Per impostazione predefinita, il server restituisce la rappresentazione completa di una risorsa dopo aver elaborato le richieste. Per migliorare le prestazioni, puoi chiedere al server di inviare solo i campi di cui hai effettivamente bisogno e ricevere quindi una risposta parziale.
Per richiedere una risposta parziale, utilizza il parametro di richiesta fields
per specificare i campi che vuoi che vengano restituiti. Puoi utilizzare questo parametro con qualsiasi richiesta che restituisce dati di risposta.
Tieni presente che il parametro fields
influisce solo sui dati di risposta e non sui dati che devi inviare, se presenti. Per ridurre la quantità di dati inviati durante la modifica delle risorse, utilizza una richiesta PATCH.
Esempio
L'esempio seguente mostra l'utilizzo del parametro fields
con un'API "Demo" generica (fittizia).
Richiesta semplice: questa richiesta HTTP GET
omette il parametro fields
e restituisce la risorsa completa.
https://www.googleapis.com/demo/v1
Risposta completa della risorsa: i dati completi della risorsa includono i seguenti campi, oltre a molti altri che sono stati omessi per brevità.
{ "kind": "demo", ... "items": [ { "title": "First title", "comment": "First comment.", "characteristics": { "length": "short", "accuracy": "high", "followers": ["Jo", "Will"], }, "status": "active", ... }, { "title": "Second title", "comment": "Second comment.", "characteristics": { "length": "long", "accuracy": "medium" "followers": [ ], }, "status": "pending", ... }, ... ] }
Richiesta di risposta parziale: la seguente richiesta per la stessa risorsa utilizza il parametro fields
per ridurre in modo significativo la quantità di dati restituiti.
https://www.googleapis.com/demo/v1?fields=kind,items(title,characteristics/length)
Risposta parziale: in risposta alla richiesta precedente, il server invia una risposta contenente solo le informazioni sul tipo, oltre a un array "items" ridotto, che include solo il titolo HTML e informazioni sulla caratteristica "length" in ogni elemento.
200 OK
{ "kind": "demo", "items": [{ "title": "First title", "characteristics": { "length": "short" } }, { "title": "Second title", "characteristics": { "length": "long" } }, ... ] }
Tieni presente che la risposta è un oggetto JSON che include solo i campi selezionati e gli oggetti principali che li contengono.
Di seguito sono riportati i dettagli su come formattare il parametro fields
, seguiti da ulteriori dettagli su cosa viene restituito esattamente nella risposta.
Riepilogo della sintassi del parametro fields
Il formato del valore del parametro di richiesta fields
si basa liberamente sulla sintassi XPath. La sintassi supportata è riassunta di seguito e altri esempi sono forniti nella sezione seguente.
- Utilizza un elenco separato da virgole per selezionare più campi.
- Utilizza
a/b
per selezionare un campob
nidificato all'interno del campoa
; utilizzaa/b/c
per selezionare un campoc
nidificato all'interno dib
.
Eccezione: per le risposte dell'API che utilizzano wrapper "data", in cui la risposta è nidificata all'interno di un oggetto
data
simile adata: { ... }
, non includere "data
" nella specifica difields
. L'inclusione dell'oggetto "data" con una specifica di fields comedata/a/b
causa un errore. Utilizza invece una specifica difields
comea/b
. - Utilizza un selettore secondario per richiedere un insieme di sottocampi specifici di array o oggetti inserendo le espressioni tra parentesi "
( )
".Ad esempio,
fields=items(id,author/email)
restituisce solo l'ID elemento e l'email dell'autore per ogni elemento nell'array "items". Puoi anche specificare un singolo sottocampo, dovefields=items(id)
è equivalente afields=items/id
. - Utilizza i caratteri jolly nelle selezioni dei campi, se necessario.
Ad esempio,
fields=items/pagemap/*
seleziona tutti gli oggetti in una pagemap.
Altri esempi di utilizzo del parametro fields
Gli esempi riportati di seguito includono descrizioni dell'impatto del valore del parametro fields
sulla risposta.
Nota: come per tutti i valori dei parametri di query, il valore del parametro fields
deve essere codificato nell'URL. Per una maggiore leggibilità, gli esempi in questo documento omettono la codifica.
- Identifica i campi che vuoi che vengano restituiti o effettua selezioni di campi.
- Il valore del parametro di richiesta
fields
è un elenco di campi separati da virgole e ogni campo è specificato rispetto alla radice della risposta. Pertanto, se esegui un'operazione list, la risposta è una raccolta e in genere include un array di risorse. Se stai eseguendo un'operazione che restituisce una singola risorsa, i campi vengono specificati rispetto a quella risorsa. Se il campo selezionato è (o fa parte di) un array, il server restituisce la parte selezionata di tutti gli elementi dell'array.
Ecco alcuni esempi a livello di raccolta:
Esempi Effetto items
Restituisce tutti gli elementi nell'array "items", inclusi tutti i campi di ogni elemento, ma nessun altro campo. etag,items
Restituisce sia il campo etag
sia tutti gli elementi nell'array "items".items/title
Restituisce solo il campo title
per tutti gli elementi dell'array "items".
Ogni volta che viene restituito un campo nidificato, la risposta include gli oggetti principali che lo contengono. I campi principali non includono altri campi secondari, a meno che non siano selezionati a loro volta in modo esplicito.context/facets/label
Restituisce solo il campo label
per tutti i membri dell'arrayfacets
, che è a sua volta nidificato nell'oggettocontext
.items/pagemap/*/title
Per ogni elemento dell'array "items", restituisce solo il campo title
(se presente) di tutti gli oggetti secondari dipagemap
.
Ecco alcuni esempi a livello di risorsa:
Esempi Effetto title
Restituisce il campo title
della risorsa richiesta.author/uri
Restituisce il sottocampo uri
dell'oggettoauthor
nella risorsa richiesta.links/*/href
Restituisce il campo href
di tutti gli oggetti secondari dilinks
. - Richiedi solo parti di campi specifici utilizzando le sottoselezioni.
- Per impostazione predefinita, se nella richiesta sono specificati particolari campi, il server restituisce gli oggetti o gli elementi dell'array nella loro interezza. Puoi specificare una risposta che includa solo determinati sottocampi. Per farlo, utilizza la sintassi di sottoselezione "
( )
", come nell'esempio seguente.Esempio Effetto items(title,author/uri)
Restituisce solo i valori di title
euri
dell'autore per ogni elemento dell'array "items".
Gestione delle risposte parziali
Dopo che un server ha elaborato una richiesta valida che include il parametro di query fields
, restituisce un codice di stato HTTP 200 OK
insieme ai dati richiesti. Se il parametro di query fields
presenta un errore o non è valido, il server restituisce un codice di stato HTTP 400 Bad Request
, insieme a un messaggio di errore che indica all'utente il problema relativo alla selezione dei campi (ad esempio, "Invalid field selection a/b"
).
Ecco l'esempio di risposta parziale mostrato nella sezione introduttiva sopra. La richiesta utilizza il parametro fields
per specificare i campi da restituire.
https://www.googleapis.com/demo/v1?fields=kind,items(title,characteristics/length)
La risposta parziale è la seguente:
200 OK
{ "kind": "demo", "items": [{ "title": "First title", "characteristics": { "length": "short" } }, { "title": "Second title", "characteristics": { "length": "long" } }, ... ] }
Nota: per le API che supportano i parametri di query per l'impaginazione dei dati (ad es. maxResults
e nextPageToken
), utilizza questi parametri per ridurre i risultati di ogni query a dimensioni gestibili. In caso contrario, potresti non ottenere i miglioramenti delle prestazioni offerti dalla risposta parziale.
Patch (aggiornamento parziale)
Puoi anche evitare di inviare dati non necessari quando modifichi le risorse. Per inviare i dati aggiornati solo per i campi specifici che stai modificando, utilizza il verbo HTTP PATCH
. Le semantiche di PATCH descritte in questo documento sono diverse (e più semplici) rispetto all'implementazione GData precedente dell'aggiornamento parziale.
Il breve esempio riportato di seguito mostra come l'utilizzo di PATCH riduce al minimo i dati da inviare per eseguire un piccolo aggiornamento.
Esempio
Questo esempio mostra una semplice richiesta PATCH per aggiornare solo il titolo di una risorsa API "Demo" generica (fittizia). La risorsa contiene anche un commento, un insieme di caratteristiche, lo stato e molti altri campi, ma questa richiesta invia solo il campo title
, poiché è l'unico campo modificato:
PATCH https://www.googleapis.com/demo/v1/324 Authorization: Bearer your_auth_token Content-Type: application/json { "title": "New title" }
Risposta:
200 OK
{ "title": "New title", "comment": "First comment.", "characteristics": { "length": "short", "accuracy": "high", "followers": ["Jo", "Will"], }, "status": "active", ... }
Il server restituisce un codice di stato 200 OK
, insieme alla rappresentazione completa della risorsa aggiornata. Poiché nella richiesta PATCH è stato incluso solo il campo title
, questo è l'unico valore diverso da prima.
Nota: se utilizzi il parametro fields
di risposta parziale in combinazione con PATCH, puoi aumentare ulteriormente l'efficienza delle richieste di aggiornamento. Una richiesta PATCH riduce solo le dimensioni della richiesta. Una risposta parziale riduce le dimensioni della risposta. Pertanto, per ridurre la quantità di dati inviati in entrambe le direzioni, utilizza una richiesta PATCH con il parametro fields
.
Semantica di una richiesta PATCH
Il corpo della richiesta PATCH include solo i campi della risorsa che vuoi modificare. Quando specifichi un campo, devi includere tutti gli oggetti principali che lo contengono, così come avviene in una risposta parziale, che restituisce gli oggetti principali che contengono i campi. I dati modificati che invii vengono uniti ai dati dell'oggetto principale, se presente.
- Aggiunta: per aggiungere un campo che non esiste già, specifica il nuovo campo e il relativo valore.
- Modifica: per modificare il valore di un campo esistente, specificalo e impostalo sul nuovo valore.
- Eliminazione: per eliminare un campo, specificalo e impostalo su
null
. Ad esempio,"comment": null
. Puoi anche eliminare un intero oggetto (se è mutabile) impostandolo sunull
. Se utilizzi la libreria client API per Java, usaData.NULL_STRING
. Per maggiori dettagli, consulta JSON null.
Nota sugli array: le richieste PATCH che contengono array sostituiscono l'array esistente con quello fornito. Non puoi modificare, aggiungere o eliminare singoli elementi in un array.
Utilizzo di PATCH in un ciclo di lettura, modifica e scrittura
Può essere utile iniziare recuperando una risposta parziale con i dati da modificare. Questo è particolarmente importante per le risorse che utilizzano gli ETag, poiché per aggiornare correttamente la risorsa devi fornire il valore ETag attuale nell'intestazione HTTP If-Match
. Dopo aver recuperato i dati, puoi modificare i valori da cambiare e inviare nuovamente la rappresentazione parziale modificata con una richiesta PATCH. Ecco un esempio che presuppone che la risorsa Demo utilizzi gli ETag:
GET https://www.googleapis.com/demo/v1/324?fields=etag,title,comment,characteristics Authorization: Bearer your_auth_token
Questa è la risposta parziale:
200 OK
{ "etag": "ETagString" "title": "New title" "comment": "First comment.", "characteristics": { "length": "short", "level": "5", "followers": ["Jo", "Will"], } }
La seguente richiesta PATCH si basa su questa risposta. Come mostrato di seguito, utilizza anche il parametro fields
per limitare i dati restituiti nella risposta PATCH:
PATCH https://www.googleapis.com/demo/v1/324?fields=etag,title,comment,characteristics Authorization: Bearer your_auth_token Content-Type: application/json If-Match: "ETagString"
{ "etag": "ETagString" "title": "", /* Clear the value of the title by setting it to the empty string. */ "comment": null, /* Delete the comment by replacing its value with null. */ "characteristics": { "length": "short", "level": "10", /* Modify the level value. */ "followers": ["Jo", "Liz"], /* Replace the followers array to delete Will and add Liz. */ "accuracy": "high" /* Add a new characteristic. */ }, }
Il server risponde con un codice di stato HTTP 200 Ok e la rappresentazione parziale della risorsa aggiornata:
200 OK
{ "etag": "newETagString" "title": "", /* Title is cleared; deleted comment field is missing. */ "characteristics": { "length": "short", "level": "10", /* Value is updated.*/ "followers": ["Jo" "Liz"], /* New follower Liz is present; deleted Will is missing. */ "accuracy": "high" /* New characteristic is present. */ } }
Creazione diretta di una richiesta PATCH
Alcune richieste PATCH devono essere basate sui dati recuperati in precedenza. Ad esempio, se vuoi aggiungere un elemento a un array e non vuoi perdere nessuno degli elementi dell'array esistenti, devi prima recuperare i dati esistenti. Analogamente, se un'API utilizza gli ETag, devi inviare il valore ETag precedente con la richiesta per aggiornare correttamente la risorsa.
Nota: puoi utilizzare un'intestazione HTTP "If-Match: *"
per forzare l'esecuzione di una richiesta PATCH quando sono in uso gli ETag. In questo caso, non è necessario eseguire la lettura prima della scrittura.
In altre situazioni, invece, puoi creare direttamente la richiesta PATCH, senza prima recuperare i dati esistenti. Ad esempio, puoi configurare facilmente una richiesta PATCH che aggiorna un campo con un nuovo valore o aggiunge un nuovo campo. Ecco un esempio:
PATCH https://www.googleapis.com/demo/v1/324?fields=comment,characteristics Authorization: Bearer your_auth_token Content-Type: application/json { "comment": "A new comment", "characteristics": { "volume": "loud", "accuracy": null } }
Con questa richiesta, se il campo "comment" ha un valore esistente, il nuovo valore lo sovrascrive; in caso contrario, il campo viene impostato sul nuovo valore. Analogamente, se esiste una caratteristica "volume", il relativo valore viene sovrascritto; in caso contrario, viene creato. Il campo "accuracy", se impostato, viene rimosso.
Gestione della risposta a una richiesta PATCH
Dopo aver elaborato una richiesta PATCH valida, l'API restituisce un codice di risposta HTTP 200 OK
insieme alla rappresentazione completa della risorsa modificata. Se l'API utilizza gli ETag, il server aggiorna i valori ETag quando elabora correttamente una richiesta PATCH, come avviene con PUT
.
La richiesta PATCH restituisce l'intera rappresentazione della risorsa, a meno che non utilizzi il parametro fields
per ridurre la quantità di dati restituiti.
Se una richiesta PATCH genera un nuovo stato della risorsa non valido dal punto di vista sintattico o semantico, il server restituisce un codice di stato HTTP 400 Bad Request
o 422 Unprocessable Entity
e lo stato della risorsa rimane invariato. Ad esempio, se provi a eliminare il valore di un campo obbligatorio, il server restituisce un errore.
Notazione alternativa quando il verbo HTTP PATCH non è supportato
Se il firewall non consente le richieste HTTP PATCH
, invia una richiesta HTTP POST
e imposta l'intestazione di override su PATCH
, come mostrato di seguito:
POST https://www.googleapis.com/... X-HTTP-Method-Override: PATCH ...
Differenza tra patch e aggiornamento
In pratica, quando invii i dati per una richiesta di aggiornamento che utilizza il verbo HTTP PUT
, devi inviare solo i campi obbligatori o facoltativi. Se invii valori per i campi impostati dal server, questi vengono ignorati. Anche se potrebbe sembrare un altro modo per eseguire un aggiornamento parziale, questo approccio presenta alcune limitazioni. Con gli aggiornamenti che utilizzano il verbo HTTP PUT
, la richiesta non va a buon fine se non fornisci i parametri obbligatori e vengono cancellati i dati impostati in precedenza se non fornisci i parametri facoltativi.
Per questo motivo, è molto più sicuro utilizzare PATCH. Fornisci i dati solo per i campi che vuoi modificare; i campi omessi non vengono cancellati. L'unica eccezione a questa regola si verifica con elementi o array ripetuti: se li ometti tutti, rimangono invariati; se ne fornisci uno, l'intero insieme viene sostituito con quello che fornisci.