Performances http HEAD vs GET

111

Je suis en train de mettre en place un service Web REST qui doit simplement répondre OUI ou NON, le plus rapidement possible.

Concevoir un service HEAD semble la meilleure façon de le faire mais j'aimerais savoir si je gagnerai vraiment du temps par rapport à une requête GET.

Je suppose que je gagne le flux de corps pour ne pas être ouvert / fermé sur mon serveur (environ 1 milliseconde?). La quantité d'octets à renvoyer étant très faible, est-ce que je gagne du temps en transport, en numéro de paquet IP?

Merci d'avance pour votre réponse!

Éditer:

Pour expliquer davantage le contexte:

  • J'ai un ensemble de services REST exécutant certains processus, s'ils sont dans un état actif.
  • J'ai un autre service REST indiquant l'état de tous ces premiers services.

Comme ce dernier service sera appelé très souvent par un très grand nombre de clients (un appel attendu toutes les 5ms), je me demandais si l'utilisation d'une méthode HEAD peut être une optimisation précieuse? Environ 250 caractères sont renvoyés dans le corps de la réponse. La méthode HEAD permet au moins de gagner le transport de ces 250 caractères, mais quel est cet impact?

J'ai essayé de comparer la différence entre les deux méthodes (HEAD vs GET), en exécutant 1000 fois les appels, mais je ne vois aucun gain du tout (<1ms) ...

Astérius
la source
2
Cela dépend également de l'approche que vous utilisez côté serveur. Le traitement d'une requête GET ou HEAD peut généralement prendre le même temps au serveur, car le serveur peut avoir besoin de connaître le corps final pour calculer la Content-Lengthvaleur d'en-tête, qui est une information importante dans une réponse à une requête HEAD. À moins qu'il n'y ait une autre approche côté serveur plus optimisée, le seul avantage est que la bande passante est économisée et que le client n'a pas à analyser le corps de la réponse. Donc, fondamentalement, les gains d'optimisation dépendent à la fois des implémentations serveur et client.
itsjavi

Réponses:

173

Un URI RESTful doit représenter une "ressource" sur le serveur. Les ressources sont souvent stockées sous la forme d'un enregistrement dans une base de données ou d'un fichier sur le système de fichiers. Sauf si la ressource est volumineuse ou lente à récupérer sur le serveur, il se peut que vous ne voyiez pas de gain mesurable en utilisant à la HEADplace de GET. Il se peut que la récupération des métadonnées ne soit pas plus rapide que la récupération de la ressource entière.

Vous pouvez implémenter les deux options et les comparer pour voir laquelle est la plus rapide, mais plutôt que de micro-optimiser, je me concentrerais sur la conception de l'interface REST idéale. Une API REST propre est généralement plus précieuse sur le long terme qu'une API kludgey qui peut ou non être plus rapide. Je ne décourage pas l'utilisation de HEAD, je suggère simplement de ne l'utiliser que si c'est le "bon" design.

Si les informations dont vous avez vraiment besoin sont des métadonnées sur une ressource qui peuvent être bien représentées dans les en-têtes HTTP, ou pour vérifier si la ressource existe ou non, HEAD peut fonctionner correctement.

Par exemple, supposons que vous souhaitiez vérifier si la ressource 123 existe. A 200signifie «oui» et a 404signifie «non»:

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

HTTP/1.1 404 Not Found
[...]

Cependant, si le "oui" ou le "non" que vous voulez de votre service REST fait partie de la ressource elle-même, plutôt que des métadonnées, vous devez utiliser GET.

Et rouge
la source
2
les meilleures choses sont toujours simples, tout comme cette réponse. Voila!
Afzal SH
Merveilleuse réponse! J'ai une question: qu'en est-il de l'utiliser comme touchcommande pour mettre à jour le nombre de vues d'une publication sur le serveur? Les données de publication ont déjà été récupérées via un /postsappel normal , je souhaite donc simplement mettre à jour le nombre de vues une fois que l'utilisateur interagit avec la publication d'une manière ou d'une autre.
aalaap le
1
@aalaap Si vous comptez mettre à jour un compteur de vues pour les HEADdemandes, vous devez le faire également pour les GETdemandes. La décision d'utiliser GETou HEADrevient finalement au client HTTP. Votre serveur doit se comporter de la même manière pour les deux types de requêtes, sauf qu'il n'y a pas de corps de réponse lors de la réponse HEAD. Quant à savoir si c'est un bon moyen d'implémenter quelque chose comme un compteur de vues, je ne suis pas sûr.
Andre D
-1 Toute information pouvant être nommée peut être une ressource. D'où Uniform Resource Locator. L'idée selon laquelle utiliser une partie du protocole HTTP, tel que conçu, est "kludgey" ou "impur" est bizarre.
Fraser
1
@Siddhartha, c'est très souvent vrai, mais pas toujours. Content-Lengthpeut être omis lors de l'utilisation Transfer-Encoding: chunked. Même avec Content-Length, il est possible que le serveur puisse obtenir la taille de la ressource et d'autres métadonnées utilisées dans les en-têtes sans récupérer la ressource réelle. Peut-être que ces métadonnées sont même mises en cache en mémoire pour un accès très rapide. Tout cela est très spécifique à la mise en œuvre.
Andre D
38

J'ai trouvé cette réponse en recherchant la même question posée par le demandeur. J'ai également trouvé ceci sur http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html :

La méthode HEAD est identique à GET sauf que le serveur NE DOIT PAS renvoyer un corps de message dans la réponse. Les méta-informations contenues dans les en-têtes HTTP en réponse à une demande HEAD DEVRAIENT être identiques aux informations envoyées en réponse à une demande GET. Cette méthode peut être utilisée pour obtenir des méta-informations sur l'entité impliquée par la demande sans transférer le corps d'entité lui-même. Cette méthode est souvent utilisée pour tester la validité, l'accessibilité et les modifications récentes des liens hypertextes.

Il me semble que la bonne réponse à la question du demandeur est que cela dépend de ce qui est représenté par le protocole REST. Par exemple, dans mon cas particulier, mon protocole REST est utilisé pour récupérer des images assez volumineuses (comme dans plus de 10K). Si j'ai un grand nombre de ces ressources vérifiées sur une base constante, et étant donné que j'utilise les en-têtes de requête, alors il serait logique d'utiliser la requête HEAD, selon les recommandations de w3.org.

Charles Thomas
la source
14

Je déconseille fortement ce genre d'approche.

Un service RESTful doit respecter la sémantique des verbes HTTP. Le verbe GET est destiné à récupérer le contenu de la ressource, tandis que le verbe HEAD ne retournera aucun contenu et pourra être utilisé, par exemple, pour voir si une ressource a changé, pour connaître sa taille ou son type, pour vérifier si elle existe, et ainsi de suite.

Et rappelez-vous: l'optimisation précoce est la racine de tout mal.

Eric Citaire
la source
8

Vos performances ne changeront guère en utilisant une requête HEAD au lieu d'une requête GET.

De plus, lorsque vous souhaitez qu'il soit REST-Ful et que vous souhaitez GET, vous devez utiliser une requête GET au lieu d'une requête HEAD.

jabbink
la source
8

GET récupère la tête + le corps, HEAD ne récupère que la tête. Ce ne devrait pas être une question d’opinion pour savoir lequel est le plus rapide. Je ne comprends pas les réponses positives ci-dessus. Si vous recherchez des informations META, optez pour HEAD, qui est conçu à cet effet.

Viktor Joras
la source
3

Je ne comprends pas votre inquiétude concernant le «flux corporel ouvert / fermé». Le corps de la réponse sera sur le même flux que les en-têtes de réponse http et ne créera PAS une deuxième connexion (qui est d'ailleurs plus de l'ordre de 3 à 6 ms).

Cela semble être une tentative d'optimisation très prématurée sur quelque chose qui ne fera tout simplement pas une différence significative, voire mesurable. La vraie différence est la conformité avec REST en général, qui recommande d'utiliser GET pour obtenir des données.

Ma réponse est NON, utilisez GET si cela a du sens, il n'y a pas de gain de performance avec HEAD.

smassey
la source
Supposons que le contenu soit de 100 Mo. La tête sera sûrement inférieure au contenu en taille. Maintenant, lorsque nous demandons cette ressource par la méthode GET ou HEAD, à votre avis, il n'y a pas de différence de performance entre eux?!
Mohammad Afrashteh
3
Le PO a indiqué 250 caractères dans le corps de la réponse. Pas 100 Mo. C'est une question complètement différente.
smassey
1

Les requêtes HEAD sont comme les requêtes GET , sauf que le corps de la réponse est vide. Ce type de requête peut être utilisé lorsque tout ce que vous voulez, ce sont des métadonnées sur un fichier, mais que vous n'avez pas besoin de transporter toutes les données du fichier.

Shadab Ali
la source
-1

Vous pouvez facilement faire un petit test pour mesurer vous-même les performances. Je pense que la différence de performance serait négligeable, car si vous ne renvoyez que «Y» ou «N» dans le corps, c'est un seul octet supplémentaire ajouté à un flux déjà ouvert.

J'irais aussi avec GET car c'est plus correct. Vous n'êtes pas censé renvoyer du contenu dans les en-têtes HTTP, uniquement des métadonnées.

AshleysBrain
la source
GET - ce n'est pas seulement mystérieux "un octet supplémentaire". Tout le corps! Dans le cas d'un gros document, il peut s'agir de quelques mégaoctets.
porfirion