Questo documento illustra alcune tecniche che puoi utilizzare per migliorare le prestazioni dell'applicazione. In alcuni casi, per illustrare le idee presentate si utilizzano esempi di altre API o di API generiche. Tuttavia, gli stessi concetti sono validi per l'API Google Mirror.
Compressione usando gzip
Un modo semplice e comodo per ridurre la larghezza di banda necessaria per ogni richiesta è abilitare la compressione gzip. Anche se ciò richiede più tempo di CPU per decomprimere i risultati, in genere il ritorno sulla spesa pubblicitaria è vantaggioso.
Per ricevere una risposta con codifica gzip, devi eseguire due operazioni: impostare un'intestazione Accept-Encoding
e modificare lo user agent in modo che contenga la stringa gzip
. Di seguito è riportato un esempio di intestazioni HTTP formattate correttamente per consentire 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 soltanto la parte dei dati che ti interessa. Ciò consente alla tua applicazione di evitare di trasferire, analizzare e archiviare i campi non necessari, in modo da utilizzare risorse come rete, CPU e memoria in modo più efficiente.
Esistono due tipi di richieste parziali:
- Risposta parziale: una richiesta in cui si specificano quali campi includere nella risposta (utilizzando il parametro di richiesta
fields
). - Patch: una richiesta di aggiornamento a cui vengono inviati solo i campi da modificare (utilizza il verbo HTTP
PATCH
).
Nelle sezioni seguenti sono disponibili maggiori dettagli sulle richieste parziali.
Risposta parziale
Per impostazione predefinita, il server restituisce la rappresentazione completa di una risorsa dopo l'elaborazione delle richieste. Per ottenere prestazioni migliori, puoi chiedere al server di inviare solo i campi di cui hai veramente bisogno e ottenere una risposta parziale.
Per richiedere una risposta parziale, utilizza il parametro di richiesta fields
per specificare i campi da restituire. Puoi utilizzare questo parametro con qualsiasi richiesta che restituisca dati di risposta.
Tieni presente che il parametro fields
influisce solo sui dati di risposta, non sui dati che devi inviare, se disponibili. Per ridurre la quantità di dati che invii quando modifichi le 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 alle risorse: i dati completi sulle risorse includono i seguenti campi, insieme 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 una 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 relative al tipo, oltre a un array di elementi essenziali che include solo il titolo HTML e le informazioni sulla lunghezza della caratteristica 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 i relativi oggetti principali.
Trovi ulteriori dettagli sul formato del parametro fields
, seguito da ulteriori dettagli su ciò che viene restituito esattamente nella risposta.
Riepilogo della sintassi del parametro Campi
Il formato del valore del parametro di richiesta fields
è vagamente basato sulla sintassi XPath. La sintassi supportata è riepilogata di seguito. Ulteriori esempi sono riportati 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 API che utilizzano wrapper "data", in cui la risposta è nidificata all'interno di un oggetto
data
simile adata: { ... }
, non includere "data
" nella specificafields
. Se includi l'oggetto dati con una specifica dei campi comedata/a/b
, si verifica un errore. È sufficiente utilizzare una specificafields
comea/b
. - Utilizza un selettore secondario per richiedere un insieme di sottocampi specifici di matrici 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 di articoli. Puoi anche specificare un singolo sottocampo, dovefields=items(id)
equivale afields=items/id
. - Utilizza i caratteri jolly nelle selezioni dei campi, se necessario.
Ad esempio,
fields=items/pagemap/*
seleziona tutti gli oggetti in una mappa di pagina.
Altri esempi di utilizzo del parametro campi
Gli esempi riportati di seguito includono descrizioni di come il valore del parametro fields
influisce sulla risposta.
Nota: come per tutti i valori dei parametri di ricerca, il valore del parametro fields
deve essere codificato tramite URL. Per una migliore leggibilità, gli esempi in questo documento omettono la codifica.
- Identifica i campi da restituire o selezionali.
- Il valore del parametro di richiesta
fields
è un elenco di campi separato da virgole e ogni campo è specificato in base 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 sono specificati in base alla risorsa. Se il campo selezionato è (o fa parte) di un array, il server restituisce la parte selezionata di tutti gli elementi nell'array.
Ecco alcuni esempi a livello di raccolta:
Esempi Effetto items
Restituisce tutti gli elementi nell'array di elementi, inclusi tutti i campi di ogni elemento, ma nessun altro campo. etag,items
Restituisce sia il campo etag
sia tutti gli elementi nell'array di elementi.items/title
Restituisce solo il campo title
per tutti gli elementi nella matrice degli elementi.
Ogni volta che viene restituito un campo nidificato, la risposta include gli oggetti principali che lo includono. I campi principali non includono altri campi secondari, a meno che non siano selezionati esplicitamente.context/facets/label
Restituisce solo il campo label
per tutti i membri dell'arrayfacets
, che è a sua volta nidificato sotto l'oggettocontext
.items/pagemap/*/title
Per ogni elemento dell'array di articoli, restituisce solo il campo title
(se presente) di tutti gli oggetti che sono figli 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 selezionazioni secondarie.
- Per impostazione predefinita, se la richiesta specifica campi specifici, il server restituisce gli oggetti o gli elementi dell'array nella loro interezza. Puoi specificare una risposta che includa solo alcuni sottocampi. A tale scopo, utilizza la sintassi di "
( )
" per la selezione secondaria, come nell'esempio seguente.Esempio Effetto items(title,author/uri)
Restituisce solo i valori di title
e diuri
dell'autore per ogni elemento nella matrice di elementi.
Gestione delle risposte parziali
Dopo aver elaborato una richiesta valida che include il parametro di ricerca fields
, un server restituisce un codice di stato HTTP 200 OK
insieme ai dati richiesti. Se il parametro di ricerca fields
contiene un errore o non è valido, il server restituisce un codice di stato HTTP 400 Bad Request
e un messaggio di errore che segnala all'utente i problemi relativi alla selezione dei campi (ad esempio "Invalid field selection a/b"
).
Ecco l'esempio di risposta parziale mostrato nella sezione introduttiva riportata 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 ha il seguente aspetto:
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 ricerca per l'impaginazione dei dati (ad esempio maxResults
e nextPageToken
), utilizza questi parametri per ridurre i risultati di ogni query a una dimensione gestibile. In caso contrario, il miglioramento delle prestazioni possibile con una risposta parziale potrebbe non essere realizzato.
Patch (aggiornamento parziale)
Puoi anche evitare di inviare dati non necessari quando modifichi le risorse. Per inviare dati aggiornati solo per i campi specifici che stai modificando, utilizza il verbo HTTP PATCH
. Le semantiche delle patch descritte in questo documento sono diverse (e più semplici) rispetto all'implementazione precedente di GData per l'aggiornamento parziale.
Il breve esempio riportato di seguito mostra come utilizzare la patch per ridurre al minimo i dati che è necessario inviare per apportare un piccolo aggiornamento.
Esempio
Questo esempio mostra una semplice richiesta di patch per l'aggiornamento solo del titolo di una risorsa API generica "Demo" dell'API. La risorsa ha anche un commento, un insieme di caratteristiche, stati e molti altri campi, ma questa richiesta invia solo il campo title
, dato che è 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é solo il campo title
è stato incluso nella richiesta di patch, questo è l'unico valore diverso da prima.
Nota: Se si utilizza il parametro risposta parziale fields
in combinazione con la patch, è possibile aumentare ulteriormente l'efficienza delle richieste di aggiornamento. Una richiesta di patch riduce solo le dimensioni della richiesta. Una risposta parziale riduce le dimensioni della risposta. Per ridurre la quantità di dati inviati in entrambe le direzioni, utilizza una richiesta di patch con il parametro fields
.
Semantica di una richiesta di patch
Il corpo della richiesta di applicazione della patch include solo i campi delle risorse che vuoi modificare. Quando specifichi un campo, devi includere tutti gli oggetti principali che li racchiudono, così come vengono restituiti con una risposta parziale. I dati modificati che invii vengono uniti ai dati dell'oggetto padre, se ce n'è uno.
- Aggiungi:per aggiungere un campo che non esiste già, specifica il nuovo campo e il relativo valore.
- Modifica:per cambiare il valore di un campo esistente, specifica il campo e impostalo sul nuovo valore.
- Elimina: per eliminare un campo, specificalo e impostalo su
null
. Ad esempio:"comment": null
. Puoi anche eliminare un intero oggetto (se è modificabile) impostandolo sunull
. Se utilizzi la libreria client dell'API Java, usaData.NULL_STRING
; per i dettagli, consulta JSON null.
Nota sugli array: le richieste di patch che contengono array sostituiscono l'array esistente con quello fornito. Non puoi modificare, aggiungere o eliminare elementi in una matrice in modo scaglionato.
Utilizzo della patch in un ciclo di lettura, modifica e scrittura
Può essere utile iniziare recuperando una risposta parziale con i dati che vuoi modificare. Ciò è particolarmente importante per le risorse che utilizzano ETag, poiché devi fornire il valore attuale dell'ETag nell'intestazione HTTP If-Match
per poter aggiornare la risorsa. Dopo aver ottenuto i dati, puoi modificare i valori da modificare e restituire la rappresentazione parziale modificata con una richiesta di patch. Ecco un esempio che presuppone che la risorsa demo utilizzi 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 di patch si basa sulla risposta. Come mostrato di seguito, utilizza anche il parametro fields
per limitare i dati restituiti nella risposta della 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 di patch
Per alcune richieste di patch, devi basarle sui dati recuperati in precedenza. Ad esempio, se vuoi aggiungere un elemento a un array e non vuoi perdere alcun elemento dell'array esistente, devi prima recuperare i dati esistenti. Analogamente, se un'API utilizza ETag, devi inviare il valore ETag precedente con la richiesta per poter aggiornare la risorsa.
Nota: puoi utilizzare un'intestazione HTTP "If-Match: *"
per forzare l'applicazione di una patch quando sono in uso gli ETag. In questo modo, non dovrai eseguire la lettura prima della scrittura.
In altre situazioni, tuttavia, puoi creare la richiesta della patch direttamente, senza prima recuperare i dati esistenti. Ad esempio, puoi facilmente configurare una richiesta di patch che aggiorna un campo inserendo un nuovo valore o aggiungendone uno nuovo. Ad 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 nel campo del commento è presente un valore, il nuovo valore lo sovrascriverà, altrimenti verrà impostato sul nuovo valore. Allo stesso modo, se esisteva una caratteristica del volume, il suo valore viene sovrascritto; in caso contrario, viene creato. Il campo di accuratezza, se impostato, viene rimosso.
Gestire la risposta a una patch
Dopo aver elaborato una richiesta di patch valida, l'API restituisce un codice di risposta HTTP 200 OK
insieme alla rappresentazione completa della risorsa modificata. Se i tag ETag vengono utilizzati dall'API, il server aggiorna i valori ETag quando elabora correttamente una richiesta di patch, proprio come avviene con PUT
.
La richiesta di 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 di applicazione genera un nuovo stato della risorsa sintatticamente o semanticamente non valido, 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 tenti di 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
, effettua 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 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. Sebbene questo possa 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 riesce se non fornisci i parametri richiesti e cancella i dati precedentemente impostati se non fornisci i parametri facoltativi.
È molto più sicuro utilizzare la patch per questo motivo. Fornisci i dati solo per i campi da modificare; quelli che ometti non vengono cancellati. L'unica eccezione a questa regola si verifica con gli elementi o gli array ripetuti: se ometti tutti questi elementi, rimarranno invariati; se fornisci uno di questi elementi, l'intero insieme viene sostituito con l'insieme che fornisci.