Linee guida HTTP

Questo documento descrive il funzionamento delle API di Google con implementazioni e versioni HTTP diverse. Se utilizzi una delle nostre librerie client generate o personalizzate (il nostro approccio consigliato per la maggior parte dei casi d'uso), non devi preoccuparti, poiché il codice fornito gestisce i problemi di basso livello della comunicazione con il server.

Tuttavia, se sei uno sviluppatore esperto e devi scrivere il tuo codice personalizzato per accedere direttamente all'interfaccia REST di un'API tramite un libreria client HTTP di tua scelta, dovresti conoscere almeno alcuni dei la semantica qui documentata (pertinente all'API scelta), nonché comprendere ciò che viene fornito dalla libreria HTTP.

Utilizzo dei protocolli di rete (HTTP/*)

Questa sezione descrive i protocolli di rete supportati (in genere una versione di HTTP) che le API Cloud possono utilizzare per comunicare tra i client e server e come ti consigliamo di utilizzarli. Vedremo nel dettaglio come le richieste e le risposte sono strutturate nella sezione seguente di seguito.

Semantica HTTP

Quando sviluppi il codice client API, segui il protocollo HTTP standard semantica. API o proxy lato server potrebbero supportare solo un sottoinsieme di funzionalità HTTP standard e potrebbero supportare anche le versioni compatibili con le versioni precedenti.

La semantica del protocollo HTTP che deve essere gestita dalle implementazioni lato server delle API è controllata dallo stack del server. Fai affidamento solo su semantica se queste caratteristiche sono documentate esplicitamente come parte della specifica dell'API, come il supporto della memorizzazione nella cache.

Versioni HTTP

I client possono utilizzare qualsiasi protocollo HTTP/*, come consentito dalla piattaforma client o dalla rete lato client o come concordato con il proxy lato server. I protocolli supportati includono HTTP/1.0, HTTP/1.1, SPDY/*, HTTP/2 e QUIC.

Alcune funzionalità dell'API potrebbero essere supportate solo da versioni più recenti dei protocolli HTTP, ad esempio: server-push e priorità; alcune sono completamente specificate solo con HTTP/2, come mentre sei in modalità full-duplex. Tieni presente i limiti dei diversi Versioni HTTP se è necessaria una di queste funzionalità come parte della specifica API.

In genere consigliamo HTTP/2 per migliorare le prestazioni e la resilienza ai guasti della rete.

Canali

I canali fanno riferimento alle connessioni di rete L4 (socket TCP o UDP). Le applicazioni client non devono fare alcuna supposizione su come i canali vengono utilizzati in fase di runtime per gestire le richieste HTTP. In quasi tutti i casi, i canali vengono da proxy per conto del processo del server.

Per i client HTTP/1.1, riutilizzare sempre le connessioni TCP (Connessione: Keep-Alive); è probabile che la libreria client HTTP gestisca un pool di connessioni per migliorare le prestazioni. Non eseguire la pipeline di richieste sullo stesso TCP connessione. Vedi HTTP e TCP per ulteriori informazioni.

I browser moderni supportano tutti SPDY/*, HTTP/2 o QUIC, che eseguono il multiplexing delle richieste su un unico canale. Il limite di connessioni tradizionali (2-10) non deve mai essere un problema, tranne quando l'implementazione del server limita il numero di istanze Richieste HTTP da un singolo client, ad esempio, 100 flussi HTTP/2 su un singolo origine dati.

HTTPS

I client possono accedere a un'API tramite HTTPS o HTTP, come supportato specifica API. La negoziazione TLS e le versioni TLS sono trasparenti al client diverse applicazioni. Per impostazione predefinita, le API Google accettano solo il traffico HTTPS.

Formati di richiesta/risposta

URL delle richieste

La mappatura JSON-REST supporta i dati delle richieste con codifica URL, nonché le richieste HTTP e il corpo della risposta usa application/json come Content-Type.

Il corpo HTTP utilizza un array JSON per supportare metodi RPC in modalità flusso, e il codice JSON può contenere un numero qualsiasi di messaggi JSON o un messaggio JSON con stato di errore.

URL di richiesta lunghi

L'URL ha un limite pratico di lunghezza, in genere compreso tra 2 k e 8 k. È applicato da alcuni browser e proxy. Se l'API utilizza richieste GET con URL che superano il limite di lunghezza, tali richieste potrebbero essere rifiutate dai browser. Per aggirare la limitazione, il codice client deve utilizzare una richiesta POST con il valore application/x-www-form-urlencoded per il Content-Type e l'intestazione HTTP X-HTTP-Method-Override: GET. Questo approccio funziona anche per le richieste DELETE.

Metodi HTTP (verbi)

Se gli URL delle richieste seguono il modello REST, i relativi metodi HTTP sono specificati nell'ambito della specifica dell'API. In particolare, ogni metodo dell'API deve essere conforme ai requisiti del protocollo HTTP in base al verbo HTTP specifico a cui il metodo dell'API viene mappato. Per maggiori dettagli, consulta la specifica del Hypertext Transfer Protocol e l'RFC del metodo PATCH.

Metodi sicuri, come come HTTP GET e HEAD non devono rappresentare un'azione diversa da recupero. In particolare, HTTP GET deve essere considerato sicuro e non devono avere effetti collaterali visibili al client.

L'idempotenza in HTTP significa che gli effetti collaterali di più richieste identiche sono gli stessi di una singola richiesta. GET, PUT e DELETE sono i metodi HTTP idempotenti pertinenti alla guida di stile. L'idempotenza è solo espressi in termini di effetti collaterali del server e non specifica nulla sulla risposta. In particolare DELETE per le risorse non esistenti deve restituire 404 (Not Found).

HTTP POST e PATCH non sono sicuri né idempotenti. (PATCH è stato introdotto nell'RFC 5789)

Verbo HTTP Sicuro Idempotente
GET
PUT  
DELETE  
POST  
PATCH  

Formati del payload

  • La richiesta e la risposta devono condividere lo stesso Content-Type, tranne quando la richiesta è un GET o un POST con un corpo "application/x-www-form-urlencoded".

  • JSON è supportato dal tipo MIME application/json. La mappatura da proto3 a JSON è specificata formalmente in JSON Mapping.

  • È possibile utilizzare i parametri del modulo (POST) al posto dei parametri di ricerca dell'URL (GET), seguendo la stessa regola di mappatura in stile REST per la mappatura dei campi di richiesta su cui eseguire query parametri. Il valore di Content-Type supportato è application/x-www-form-urlencoded.

Streaming

Half-duplex e full-duplex

HTTP è un protocollo di richiesta-risposta che consente al corpo della richiesta o della risposta la distribuzione su diversi trasporti orientati al flusso come TCP (HTTP/1.x) o le sue varianti multiplex (SPDY, HTTP/2, QUIC).

In qualità di sviluppatore client, la tua applicazione può produrre il corpo della richiesta modalità flusso di dati, ovvero flusso client. Allo stesso modo, l'applicazione può anche consumare il corpo della risposta in modalità flusso di dati, ovvero flusso di server.

Tuttavia, la specifica HTTP non specifica se un il server può eseguire il flusso indietro del corpo della risposta (ad eccezione delle risposte di errore) quando il corpo della richiesta è in attesa. Questa semantica è nota come streaming full-duplex. Sebbene molti oggetti HTTP i software client/server/proxy consentono lo streaming full-duplex, anche per HTTP/1.1, per evitare problemi di interoperabilità, le API Cloud basate su HTTP sono limitate a: solo per lo streaming semiduplex.

Per impostazione predefinita, i metodi di streaming bidirezionale nelle API Cloud presuppongono la semantica full-duplex. In altre parole, non è sicuro utilizzare HTTP per richiamare un metodo di questo tipo. Se un flusso di dati è solo dual-duplex (come imposto dal server), il documento API deve specificare chiaramente il comportamento semiduplex.

Per i client del browser, la semantica HTTP standard è ulteriormente vincolata dal le API di rete del browser. Attualmente i browser supportano solo lo streaming del server (che generalmente rispetta il framing a livello di trasporto) tramite XHR o Fetch. L'API Fetch utilizza whatwg Streams.

A causa delle limitazioni del browser, le API Cloud che richiedono il supporto del browser devono evitare lo streaming client e lo streaming full-duplex oppure fornire un'API separata specificamente per i client browser.

In generale, i flussi di dati client su Internet sono meno utili di flusso server. Questo perché l'utilizzo dello streaming client spesso porta a un servizio con stato, che influisce negativamente sul bilanciamento del carico e rende il sistema più vulnerabile a guasti o attacchi. Lo streaming dal server, invece, può essere utile perché può ridurre notevolmente la latenza sulle reti con ritardi RTT lunghi.

Codifica dei messaggi

I messaggi JSON durante il flusso di dati vengono codificati come array di messaggi JSON. Il corpo della richiesta o della risposta rimarrà un tipo MIME JSON valido.

Esempio di codifica dello stream client:

1 <length> <message-bytes> 1 <length> <message-bytes>   EOF

Esempio di codifica dello stream del server:

1 <length> <message-bytes>   2 <length> <status-bytes> EOF

Codifica a livello di cavo: la definizione di StreamBody è significativa solo nella sua allocazione di ID tag per il campo "messages" e "status" sarà codificato con 1-2 byte per i messaggi normali, quindi il totale l'overhead è di 2-3 byte per messaggio.

Per supportare gli stream con codifica base64 è necessario un campo di riempimento facoltativo:

message StreamBody {
  repeated bytes message = 1;
  google.rpc.Status status = 2;
  repeated bytes padding = 15;   // max one-byte tag-id: xxx01111
}

I messaggi di errore devono essere aggiunti come ultimo elemento dell'array JSON o protobuf, nello stesso formato dei messaggi normali.

Gestione dello stato

Il comportamento di metà chiusura è ben definito in qualsiasi versione HTTP per un client o un server per segnalare all'altro capo che il corpo è completo.

In particolare, il codice client è libero di completare la richiesta mentre è ancora in attesa della risposta. Analogamente, un client potrebbe visualizzare una risposta completata quando il corpo della richiesta è ancora in fase di scrittura sul server. Lo standard HTTP si aspetta che il client interrompa o completi la richiesta quando viene completata la risposta in modo imprevisto, solitamente con uno stato di errore. Ciò significa che in condizioni normali il server non dovrebbe completare una risposta quando il client sta ancora inviando la richiesta.

Annullamento

L'assistenza per l'annullamento consente a un client di interrompere una richiesta quando la richiesta o la risposta è ancora in attesa.

Non esiste un supporto affidabile per la cancellazione per i client HTTP/1.* libero di chiudere una connessione TCP dopo il completamento della richiesta senza interrompendo la transazione di richiesta/risposta. Un FIN TCP, in HTTP/1.1, non dovrebbe interpretabile come un annullamento, anche quando la connessione è contrassegnata come keep-alive one (Connessione: Keep-Alive).

Tuttavia, dopo la chiusura della connessione TCP da parte del client, se il server tenta dati al client, viene generato un RST, che può attivare l'annullamento.

Tieni inoltre presente che l'annullamento è un problema anche per le API non di streaming. In particolare questo caso quando la risposta prevede un lungo polling e quindi la connessione potrebbe rimanere inattiva. per un periodo di tempo prolungato.

La cancellazione esplicita è supportata con SPDY, HTTP/2 e QUIC, in particolare con messaggio di chiusura.

Keep-alive

Il supporto keep-alive consente a un client o server di rilevare un peer in errore, anche in in caso di perdita di pacchetti o errori di rete.

In HTTP/1.1 non è supportato il keep-alive perché il keep-alive TCP non è un approccio valido.

QUIC o HTTP/2 offrono messaggi di controllo speciali allo scopo di implementare il supporto keep-alive da parte delle applicazioni, inclusi i browser.

Tuttavia, il keep-alive e il rilevamento degli errori affidabili richiederanno probabilmente un client libreria con il supporto lato server necessario: eseguire flussi di dati di lunga durata su internet è spesso soggetta a errori quando si utilizza HTTP di base come protocollo di comunicazione.

Controllo del flusso

Il supporto del controllo di flusso richiede al client di propagare il livello di trasporto di controllo del flusso all'applicazione client. Il meccanismo effettivo dipende dall'impostazione dell'API client HTTP utilizzata dall'applicazione client. Ad esempio: hai bisogno di bloccare le scritture e le letture o le letture e scritture non bloccanti con il supporto esplicito di controllo del flusso consentire alle applicazioni di gestire e rispettare gli eventi di controllo del flusso, al fine di evitare per evitare il sovraccarico del client o del server.

HTTP/1.1 si basa sul controllo del flusso TCP.

SPDY e HTTP/2 hanno un proprio controllo del flusso a livello di stream, che è inoltre soggetto al controllo del flusso TCP a livello di connessione poiché le richieste vengono multiplexate su una singola connessione TCP.

QUIC funziona su UDP e quindi gestisce il controllo del flusso completamente autonomamente.