http HEAD vs GET rendimiento

111

Estoy configurando un servicio web REST que solo necesito responder SÍ o NO, lo más rápido posible.

Diseñar un servicio HEAD parece la mejor manera de hacerlo, pero me gustaría saber si realmente ganaré algo de tiempo en lugar de hacer una solicitud GET.

Supongo que obtengo que el flujo del cuerpo no esté abierto / cerrado en mi servidor (¿aproximadamente 1 milisegundo?). Dado que la cantidad de bytes a devolver es muy baja, ¿gano algo de tiempo en transporte, en número de paquete IP?

¡Gracias por adelantado por tu respuesta!

Editar:

Para explicar más el contexto:

  • Tengo un conjunto de servicios REST que ejecutan algunos procesos, si están en un estado activo.
  • Tengo otro servicio REST indicando el estado de todos estos primeros servicios.

Dado que ese último servicio será llamado muy a menudo por un gran número de clientes (se espera una llamada cada 5 ms), me preguntaba si el uso de un método HEAD puede ser una optimización valiosa. Se devuelven unos 250 caracteres en el cuerpo de respuesta. El método HEAD al menos gana el transporte de estos 250 caracteres, pero ¿cuál es ese impacto?

Intenté comparar la diferencia entre los dos métodos (HEAD vs GET), ejecutando 1000 veces las llamadas, pero no veo ninguna ganancia (<1ms) ...

Asterio
fuente
2
También depende del enfoque que utilice en el lado del servidor. Por lo general, el servidor puede tardar el mismo tiempo en procesar una solicitud GET o una solicitud HEAD, porque es posible que el servidor necesite conocer el cuerpo final para calcular el Content-Lengthvalor del encabezado, que es una información importante en una respuesta a una solicitud HEAD. A menos que exista algún otro enfoque del lado del servidor más optimizado, el único beneficio es que se ahorra ancho de banda y el cliente no tiene que analizar el cuerpo de la respuesta. Entonces, básicamente, las ganancias de optimización dependen de las implementaciones del servidor y del cliente.
itsjavi

Respuestas:

173

Un URI RESTful debe representar un "recurso" en el servidor. Los recursos a menudo se almacenan como un registro en una base de datos o un archivo en el sistema de archivos. A menos que el recurso sea grande o sea lento para recuperar en el servidor, es posible que no vea una ganancia medible al usar en HEADlugar de GET. Podría ser que recuperar los metadatos no sea más rápido que recuperar el recurso completo.

Podría implementar ambas opciones y compararlas para ver cuál es más rápido, pero en lugar de micro-optimizar, me concentraría en diseñar la interfaz REST ideal. Una API REST limpia suele ser más valiosa a largo plazo que una API kludgey que puede ser más rápida o no. No estoy desanimando el uso de HEAD, solo sugiero que solo lo use si es el diseño "correcto".

Si la información que necesita realmente son metadatos sobre un recurso que se puede representar bien en los encabezados HTTP, o para verificar si el recurso existe o no, HEADpodría funcionar bien.

Por ejemplo, suponga que desea comprobar si existe el recurso 123. A 200significa "sí" y a 404significa "no":

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

HTTP/1.1 404 Not Found
[...]

Sin embargo, si el "sí" o "no" que desea de su servicio REST es parte del recurso en sí, en lugar de metadatos, debe usar GET.

Y Rojo
fuente
2
las mejores cosas son siempre simples, como esta respuesta. ¡Voila!
Afzal SH
¡Maravillosa respuesta! Tengo una pregunta: ¿Qué tal si lo usas como touchcomando para actualizar el recuento de vistas de una publicación en el servidor? Los datos de la publicación ya se han recuperado mediante una /postsllamada normal , por lo que solo quiero actualizar el recuento de vistas después de que el usuario interactúa con la publicación de alguna manera.
aalaap
1
@aalaap Si va a actualizar un contador de vistas para las HEADsolicitudes, debe hacerlo también para las GETsolicitudes. La decisión de utilizar GETo HEADdepende en última instancia del cliente HTTP. Su servidor debe comportarse de la misma manera para ambos tipos de solicitud, excepto que no hay un cuerpo de respuesta al responder HEAD. En cuanto a si esta es una buena manera de implementar algo como un contador de vistas, no estoy seguro.
Andre D
-1 Cualquier información que se pueda nombrar puede ser un recurso. Por lo tanto, localizador uniforme de recursos. La idea de que usar parte del protocolo HTTP, como está diseñado, es "torpe" o "sucio" es extraña.
Fraser
1
@Siddhartha, eso a menudo es cierto, pero no siempre. Content-Lengthse puede omitir al usar Transfer-Encoding: chunked. Incluso con Content-Length, es posible que el servidor pueda obtener el tamaño del recurso y otros metadatos usados ​​en los encabezados sin obtener el recurso real. Quizás esos metadatos se almacenan en caché en la memoria para un acceso muy rápido. Todo eso es muy específico de la implementación.
Andre D
38

Encontré esta respuesta al buscar la misma pregunta que hizo el solicitante. También encontré esto en http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html :

El método HEAD es idéntico a GET, excepto que el servidor NO DEBE devolver un cuerpo de mensaje en la respuesta. La metainformación contenida en los encabezados HTTP en respuesta a una solicitud HEAD DEBERÍA ser idéntica a la información enviada en respuesta a una solicitud GET. Este método se puede utilizar para obtener metainformación sobre la entidad implícita en la solicitud sin transferir la entidad-cuerpo en sí. Este método se utiliza a menudo para probar enlaces de hipertexto para verificar su validez, accesibilidad y modificaciones recientes.

Me parecería que la respuesta correcta a la pregunta del solicitante es que depende de lo que representa el protocolo REST. Por ejemplo, en mi caso particular, mi protocolo REST se usa para recuperar imágenes bastante grandes (como en más de 10K). Si tengo una gran cantidad de estos recursos que se verifican de manera constante, y dado que uso los encabezados de solicitud, entonces tendría sentido usar la solicitud HEAD, según las recomendaciones de w3.org.

Charles Thomas
fuente
14

Desaconsejo firmemente este tipo de enfoque.

Un servicio RESTful debe respetar la semántica de los verbos HTTP. El verbo GET está destinado a recuperar el contenido del recurso, mientras que el verbo HEAD no devolverá ningún contenido y puede usarse, por ejemplo, para ver si un recurso ha cambiado, para saber su tamaño o su tipo, para verificar si existe, y así sucesivamente.

Y recuerde: la optimización temprana es la raíz de todos los males.

Eric Citaire
fuente
8

Su rendimiento difícilmente cambiará al usar una solicitud HEAD en lugar de una solicitud GET.

Además, cuando desee que sea REST-ful y desee obtener datos, debe usar una solicitud GET en lugar de una solicitud HEAD.

jabbink
fuente
8

GET busca cabeza + cuerpo, HEAD solo busca cabeza. No debería ser una cuestión de opinión cuál es más rápido. No entiendo las respuestas arriba votadas. Si está buscando información META, elija HEAD, que está diseñada para este propósito.

Viktor Joras
fuente
3

No entiendo su preocupación por el 'flujo del cuerpo abierto / cerrado'. El cuerpo de la respuesta estará sobre el mismo flujo que los encabezados de respuesta http y NO creará una segunda conexión (que por cierto está más en el rango de 3-6 ms).

Esto parece un intento de optimización muy prematuro en algo que simplemente no hará una diferencia significativa o medible. La verdadera diferencia es la conformidad con REST en general, que recomienda usar GET para obtener datos.

Mi respuesta es NO, use GET si tiene sentido, no hay ganancia de rendimiento usando HEAD.

smassey
fuente
Suponga que el contenido es de 100 MB. Seguramente la cabeza tendrá menos tamaño que el contenido. Ahora, cuando solicitamos ese recurso mediante el método GET o HEAD, en su opinión, ¿no hay diferencia de rendimiento entre ellos?
Mohammad Afrashteh
3
El OP indicó 250 caracteres en el cuerpo de la respuesta. No 100 MB. Esa es una pregunta completamente diferente.
smassey
1

Las solicitudes HEAD son como las solicitudes GET , excepto que el cuerpo de la respuesta está vacío. Este tipo de solicitud se puede utilizar cuando todo lo que desea son metadatos sobre un archivo, pero no necesita transportar todos los datos del archivo.

Shadab Ali
fuente
-1

Puede realizar fácilmente una pequeña prueba para medir el rendimiento usted mismo. Creo que la diferencia de rendimiento sería insignificante, porque si solo devuelve 'Y' o 'N' en el cuerpo, es un solo byte adicional agregado a una transmisión ya abierta.

También iría con GET ya que es más correcto. Se supone que no debes devolver contenido en encabezados HTTP, solo metadatos.

AshleysCerebro
fuente
GET: no es sólo un misterioso "byte extra". ¡Solo cuerpo entero! En el caso de un documento grande, podría ser de algunos megabytes.
porfirion