http HEAD vs GET prestazioni


111

Sto configurando un servizio web REST che deve solo rispondere SÌ o NO, il più velocemente possibile.

Progettare un servizio HEAD sembra il modo migliore per farlo, ma vorrei sapere se avrò davvero un po 'di tempo rispetto a una richiesta GET.

Suppongo di ottenere il flusso del corpo per non essere aperto / chiuso sul mio server (circa 1 millisecondo?). Poiché la quantità di byte da restituire è molto bassa, guadagno tempo nel trasporto, nel numero di pacchetti IP?

Grazie in anticipo per la tua risposta!

Modificare:

Per spiegare ulteriormente il contesto:

  • Ho una serie di servizi REST che eseguono alcuni processi, se sono in uno stato attivo.
  • Ho un altro servizio REST che indica lo stato di tutti questi primi servizi.

Dato che quest'ultimo servizio verrà chiamato molto spesso da un insieme molto ampio di client (una chiamata prevista ogni 5 ms), mi chiedevo se l'utilizzo di un metodo HEAD possa essere un'ottimizzazione preziosa? Vengono restituiti circa 250 caratteri nel corpo della risposta. Il metodo HEAD guadagna almeno il trasporto di questi 250 caratteri, ma qual è questo impatto?

Ho provato a confrontare la differenza tra i due metodi (HEAD vs GET), eseguendo 1000 volte le chiamate, ma non vedo alcun guadagno (<1ms) ...


2
Dipende anche dall'approccio che utilizzi sul lato server. Di solito può essere necessario lo stesso tempo del server per elaborare una richiesta GET o una richiesta HEAD, perché il server potrebbe aver bisogno di conoscere il corpo finale per calcolare il Content-Lengthvalore dell'intestazione, che è un'informazione importante in una risposta a una richiesta HEAD. A meno che non esista un altro approccio lato server più ottimizzato, l'unico vantaggio è che la larghezza di banda viene salvata e il client non deve analizzare il corpo della risposta. Quindi fondamentalmente i guadagni di ottimizzazione dipendono dalle implementazioni sia del server che del client.
itsjavi

Risposte:


173

Un URI RESTful dovrebbe rappresentare una "risorsa" sul server. Le risorse sono spesso archiviate come record in un database o in un file sul filesystem. A meno che la risorsa non sia grande o sia lenta da recuperare sul server, potresti non vedere un guadagno misurabile utilizzando HEADinvece di GET. Potrebbe essere che il recupero dei metadati non sia più veloce del recupero dell'intera risorsa.

Potresti implementare entrambe le opzioni e confrontarle per vedere quale è più veloce, ma invece di micro-ottimizzare, mi concentrerei sulla progettazione dell'interfaccia REST ideale. Un'API REST pulita di solito è più preziosa a lungo termine di un'API kludgey che può o meno essere più veloce. Non sto scoraggiando l'uso di HEAD, sto solo suggerendo di usarlo solo se è il design "giusto".

Se le informazioni di cui hai veramente bisogno sono i metadati su una risorsa che può essere rappresentata bene nelle intestazioni HTTP, o per controllare se la risorsa esiste o meno, HEADpotrebbe funzionare bene.

Ad esempio, supponi di voler controllare se la risorsa 123 esiste. A 200significa "sì" e un 404significa "no":

HEAD /resources/123 HTTP/1.1
[...]

HTTP/1.1 404 Not Found
[...]

Tuttavia, se il "sì" o il "no" che desideri dal tuo servizio REST fa parte della risorsa stessa, piuttosto che dei metadati, dovresti usare GET.


2
le cose migliori sono sempre semplici, proprio come questa risposta. Ecco!
Afzal SH

Risposta meravigliosa! Ho una domanda: che ne dici di usarlo come touchcomando per aggiornare il conteggio delle visualizzazioni di un post sul server? I dati del post sono già stati recuperati tramite una normale /postschiamata, quindi voglio solo aggiornare il conteggio delle visualizzazioni dopo che l'utente ha interagito in qualche modo con il post.
aalaap

1
@aalaap Se hai intenzione di aggiornare un contatore di visualizzazioni per le HEADrichieste, dovresti farlo anche per le GETrichieste. La decisione di utilizzare GETo HEADspetta in ultima analisi al client HTTP. Il tuo server dovrebbe comportarsi allo stesso modo per entrambi i tipi di richiesta, tranne per il fatto che non c'è il corpo della risposta quando risponde HEAD. Per quanto riguarda se questo è un buon modo per implementare qualcosa come un contatore di visualizzazioni, non sono sicuro.
Andre D

-1 Qualsiasi informazione che può essere nominata può essere una risorsa. Quindi Uniform Resource Locator. L'idea che l'utilizzo di una parte del protocollo HTTP, come previsto, sia "kludgey" o "impuro" è bizzarra.
Fraser

1
@ Siddhartha, molto spesso è vero, ma non sempre. Content-Lengthpuò essere omesso quando si utilizza Transfer-Encoding: chunked. Anche con Content-Length, è possibile che il server possa ottenere la dimensione della risorsa e altri metadati utilizzati nelle intestazioni senza recuperare la risorsa effettiva. Forse quei metadati vengono persino memorizzati nella cache per un accesso molto veloce. È tutto molto specifico per l'implementazione.
Andre D,

38

Ho trovato questa risposta cercando la stessa domanda posta dal richiedente. Ho anche trovato questo su http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html :

Il metodo HEAD è identico a GET tranne per il fatto che il server NON DEVE restituire il corpo del messaggio nella risposta. Le metainformazioni contenute nelle intestazioni HTTP in risposta a una richiesta HEAD DOVREBBE essere identiche alle informazioni inviate in risposta a una richiesta GET. Questo metodo può essere utilizzato per ottenere metainformazioni sull'entità implicita nella richiesta senza trasferire l'ente-corpo stesso. Questo metodo viene spesso utilizzato per testare la validità, l'accessibilità e le modifiche recenti dei collegamenti ipertestuali.

Mi sembra che la risposta corretta alla domanda del richiedente sia che dipende da ciò che è rappresentato dal protocollo REST. Ad esempio, nel mio caso particolare, il mio protocollo REST viene utilizzato per recuperare immagini abbastanza grandi (come in più di 10K). Se ho un gran numero di tali risorse controllate su base costante, e dato che utilizzo le intestazioni della richiesta, allora avrebbe senso usare la richiesta HEAD, secondo le raccomandazioni di w3.org.


14

Sconsiglio vivamente questo tipo di approccio.

Un servizio RESTful dovrebbe rispettare la semantica dei verbi HTTP. Il verbo GET ha lo scopo di recuperare il contenuto della risorsa, mentre il verbo HEAD non restituirà alcun contenuto e può essere utilizzato, ad esempio, per vedere se una risorsa è cambiata, per conoscere la sua dimensione o il suo tipo, per verificare se esiste e così via.

E ricorda: l'ottimizzazione iniziale è la radice di tutti i mali.


8

Le tue prestazioni difficilmente cambieranno utilizzando una richiesta HEAD invece di una richiesta GET.

Inoltre, quando vuoi che sia REST-full e vuoi OTTENERE i dati dovresti usare una richiesta GET invece di una richiesta HEAD.


8

GET recupera testa + corpo, HEAD recupera solo testa. Non dovrebbe essere una questione di opinione quale sia il più veloce. Non capisco le risposte sopravvalutate. Se stai cercando informazioni META, scegli HEAD, che è pensato per questo scopo.


3

Non capisco la tua preoccupazione per il "flusso corporeo aperto / chiuso". Il corpo della risposta sarà sullo stesso flusso delle intestazioni della risposta http e NON creerà una seconda connessione (che tra l'altro è più nell'intervallo di 3-6 ms).

Questo sembra un tentativo di ottimizzazione molto precoce su qualcosa che semplicemente non farà una differenza significativa o addirittura misurabile. La vera differenza è la conformità con REST in generale, che consiglia di utilizzare GET per ottenere i dati.

La mia risposta è NO, usa GET se ha senso, non c'è guadagno di prestazioni usando HEAD.


Supponiamo che il contenuto sia 100 MB. Sicuramente la testa sarà inferiore al contenuto in termini di dimensioni. Ora, quando richiediamo quella risorsa con il metodo GET o HEAD secondo te non c'è differenza di prestazioni tra loro ?!
Mohammad Afrashteh

3
L'OP ha dichiarato 250 caratteri nel corpo della risposta. Non 100 MB. Questa è una domanda completamente diversa.
smassey

1

Le richieste HEAD sono come le richieste GET , tranne per il fatto che il corpo della risposta è vuoto. Questo tipo di richiesta può essere utilizzato quando tutto ciò che desideri sono i metadati su un file ma non è necessario trasportare tutti i dati del file.


-1

Potresti facilmente fare un piccolo test per misurare tu stesso le prestazioni. Penso che la differenza di prestazioni sarebbe trascurabile, perché se stai restituendo solo "Y" o "N" nel corpo, è un singolo byte aggiuntivo aggiunto a un flusso già aperto.

Vorrei anche andare con GET poiché è più corretto. Non dovresti restituire contenuto nelle intestazioni HTTP, solo metadati.


GET - non è solo un misterioso "singolo byte extra". Solo tutto il corpo! Nel caso di documenti di grandi dimensioni potrebbero essere alcuni megabyte.
porfirion
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.