Quel est le code de réponse REST correct pour une requête valide mais une donnée vide?

Par exemple, vous exécutez une requête GET pour les users/9 mais aucun utilisateur n’a le numéro 9. Quel est le meilleur code de réponse?

  • 200 OK
  • 202 Accepté
  • 204 Pas de contenu
  • 400 mauvaise demande
  • 404 Introuvable

TL; DR: Utiliser 404

Voir ce blog . Cela explique très bien.

Résumé des commentaires du blog sur 204 :

  1. 204 No Content n’est pas très utile en tant que code de réponse pour un navigateur (bien que selon les spécifications HTTP, les navigateurs doivent le comprendre comme un code de réponse «ne pas modifier l’affichage»).
  2. 204 No Content est cependant très utile pour les services Web ajax qui peuvent vouloir indiquer le succès sans avoir à renvoyer quelque chose. (Surtout dans les cas comme DELETE ou POST qui ne nécessitent pas de feedback).

La réponse à votre question est donc 404 dans votre cas. 204 est un code de réponse spécialisé que vous ne devriez pas souvent retourner dans un navigateur en réponse à un GET .

Les autres codes de réponse sont encore moins appropriés que 204 et 404 .

  1. 200 devrait être retourné avec le corps de tout ce que vous avez récupéré avec succès. Pas approprié lorsque l’entité que vous récupérez n’existe pas.
  2. 202 est utilisé lorsque le serveur a commencé à travailler sur un object, mais que l’object n’est pas encore complètement prêt. Certainement pas le cas ici. Vous n’avez ni commencé ni commencé la construction de l’utilisateur 9 en réponse à une requête GET . Cela enfreint toutes sortes de règles.
  3. 400 est utilisé en réponse à une requête HTTP mal formatée (par exemple, en-têtes HTTP mal formés, segments mal ordonnés, etc.). Cela sera presque certainement géré par le framework que vous utilisez. Vous ne devriez pas avoir à faire face à cela, sauf si vous écrivez votre propre serveur à partir de zéro. Modifier : les RFC plus récents permettent désormais d’utiliser 400 pour les requêtes sémantiquement invalides.

La description de Wikipedia des codes de statut HTTP est particulièrement utile. Vous pouvez également voir les définitions dans le document HTTP / 1.1 RFC2616 sur http://www.w3.org

Je m’oppose fortement à la norme 404 en faveur de 204 ou 200 avec des données vides.

La requête a été reçue et correctement traitée – elle a déclenché le code de l’application sur le serveur. On ne peut donc pas vraiment dire qu’il s’agissait d’une erreur client et toute la classe des codes d’erreur client (4xx) ne convient pas.

Plus important encore, 404 peut se produire pour un certain nombre de raisons techniques. Par exemple, l’application est temporairement désactivée ou désinstallée sur le serveur, les problèmes de connexion proxy et autres encore. Par conséquent, le client ne peut pas faire la distinction entre un 404 qui signifie “jeu de résultats vide” et un 404 qui signifie “le service est introuvable, réessayez plus tard”.

Cela peut être fatal: imaginez un service de comptabilité dans votre entreprise qui répertorie tous les employés en raison d’un bonus annuel. Malheureusement, la fois où il est appelé, il retourne un 404. Cela signifie-t-il que personne ne doit payer un bonus ou que l’application est actuellement hors service pour un nouveau déploiement?

-> Pour les applications qui se soucient de la qualité de leurs données, le 404 est donc pratiquement impossible.

En outre, de nombreux frameworks clients répondent à un 404 en lançant une exception sans poser d’autres questions. Cela oblige le développeur client à intercepter cette exception, à l’évaluer, puis à décider en fonction de cela s’il doit la consigner en tant qu’erreur détectée par exemple par un composant de surveillance ou s’il doit l’ignorer. Cela ne me semble pas joli non plus.

Le seul avantage de 404 sur 204 est qu’il peut renvoyer une entité de réponse pouvant contenir des informations sur la raison pour laquelle la ressource demandée n’a pas été trouvée. Mais si cela est vraiment pertinent, on peut aussi envisager d’utiliser une réponse 200 OK et concevoir le système de manière à permettre des réponses d’erreur dans les données utiles. Alternativement, on pourrait utiliser la charge utile de la réponse 404 pour renvoyer des informations structurées à l’appelant. S’il reçoit par exemple une page html au lieu de XML ou JSON qu’il peut parsingr, cela indique que quelque chose de technique s’est mal passé au lieu d’une réponse “sans résultat” qui pourrait être valable du sharepoint vue de l’appelant. Ou on pourrait utiliser un en-tête de réponse HTTP pour cela.

Pourtant, je préférerais un 204 ou 200 avec une réponse vide si. Le statut de l’exécution technique de la demande est ainsi séparé du résultat logique de la demande. 2xx signifie “exécution technique ok, c’est le résultat, faites-le”.

Je pense que dans la plupart des cas, le client doit décider si un résultat vide est acceptable ou non. En retournant 404 malgré une exécution technique correcte, le client peut décider de considérer les cas comme des erreurs qui ne sont tout simplement pas des erreurs.

Une autre analogie rapide: renvoyer 404 pour “aucun résultat trouvé” revient à lancer une exception DatabaseConnectionException si une requête SQL n’a renvoyé aucun résultat. Cela peut faire le travail, mais il y a beaucoup de causes techniques possibles qui font la même exception et qui seraient alors confondues avec un résultat valide.

Si l’on s’attend à ce que la ressource existe, mais qu’elle soit vide, je dirais qu’il serait peut-être plus simple d’obtenir un 200 OK avec une représentation indiquant que la chose est vide.

Donc, je préférerais / choses renvoyer un 200 OK avec {“Items”: []} qu’un 204 avec rien du tout, car de cette manière une collection avec 0 éléments peut être traitée de la même manière qu’une collection avec un ou plus d’article en elle.

Je voudrais juste laisser le 204 No Content for PUTs et DELETE, où il se peut qu’il n’y ait pas de représentation utile.

Dans le cas où / chose / 9 n’existe pas vraiment, un 404 est approprié.

Dans les projets précédents, j’ai utilisé 404. S’il n’y a pas d’utilisateur 9, alors l’object n’a pas été trouvé. Par conséquent, 404 non trouvé est approprié.

Car object existe, mais il n’y a pas de données, 204 No Content serait approprié. Je pense que dans votre cas, l’object n’existe pas .

Au début, je pensais qu’un 204 aurait du sens, mais après les discussions, je crois que 404 est la seule réponse correcte. Considérez les données suivantes:

Utilisateurs: John, Peter

 METHOD URL STATUS RESPONSE GET /users 200 [John, Peter] GET /users/john 200 John GET /users/kyle 404 Not found GET /users?name=kyle` 200 [] DELETE /users/john 204 No Content 

Quelques antécédents:

  1. la recherche renvoie un tableau, il n’y a juste pas de correspondance mais il a du contenu: un tableau vide .

  2. 404 est bien sûr mieux connu pour les URL qui ne sont pas supscopes par le serveur demandé, mais une ressource manquante est en fait la même.
    Même si /users/:name est associé à users/kyle , l’utilisateur Kyle n’est pas une ressource disponible, donc un 404 s’applique toujours. Ce n’est pas une requête de recherche, c’est une référence directe par une URL dynamic .

En tout cas, mes deux cents 🙂

Selon w3 post,

200 OK

La demande a réussi. Les informations renvoyées avec la réponse dépendent de la méthode utilisée dans la demande

202 Accepté

La demande a été acceptée pour traitement, mais le traitement n’a pas été terminé.

204 Pas de contenu

Le serveur a rempli la demande mais n’a pas besoin de renvoyer un corps d’entité et peut vouloir renvoyer des métainformations mises à jour.

400 mauvaise demande

La requête n’a pas pu être comprise par le serveur en raison d’une syntaxe incorrecte. Le client NE DOIT PAS répéter la demande sans modifications

401 non autorisé

La demande nécessite une authentification de l’utilisateur. La réponse DOIT inclure un champ d’en-tête WWW-Authenticate

404 Introuvable

Le serveur n’a rien trouvé correspondant à l’URI de demande. Aucune indication n’est donnée quant à savoir si la condition est temporaire ou permanente

Pour résumer ou simplifier,

2xx: Données facultatives: URI bien formé: les critères ne font pas partie de l’URI: Si le critère est facultatif, il peut être spécifié dans @RequestBody et que @RequestParam doit aboutir à 2xx. Exemple: filtrer par nom / statut

4xx: Données attendues: URI mal formé: les critères font partie de l’URI: si le critère est obligatoire et ne peut être spécifié que dans @PathVariable, il doit alors conduire à 4xx. Exemple: recherche par identifiant unique.

Ainsi pour la situation demandée: “users / 9” serait 4xx (éventuellement 404) Mais pour “users? Name = superman” devrait être 2xx (éventuellement 204)

Il y a deux questions posées. Un dans le titre et un dans l’exemple. Je pense que cela a en partie provoqué une controverse quant à la réponse appropriée.

Le titre de la question concerne les données vides. Les données vides sont des données fixes mais ne sont pas identiques à aucune donnée. Cela suggère donc de demander un ensemble de résultats, c’est-à-dire une liste, peut-être de /users . Si une liste est vide, c’est toujours une liste, donc un 204 (No Content) est le plus approprié. Vous venez de demander une liste d’utilisateurs et vous en avez reçu une, il se trouve qu’il n’y a aucun contenu.

L’exemple fourni à la place concerne un object spécifique, un utilisateur /users/9 . Si l’utilisateur n ° 9 n’est pas trouvé, aucun object utilisateur n’est renvoyé. Vous avez demandé une ressource spécifique (un object utilisateur) et ne l’avez pas reçue car elle n’a pas été trouvée. Un 404 est donc approprié.

Je pense que le moyen de résoudre ce problème est que si vous pouvez utiliser la réponse de la manière attendue sans append d’instruction conditionnelle, utilisez un 204 sinon utilisez un 404.

Dans mes exemples, je peux parcourir une liste vide sans vérifier si elle contient du contenu, mais je ne peux pas afficher les données d’object utilisateur sur un object nul sans casser quelque chose ou append une vérification pour voir si elle est nulle.

Vous pouvez bien sûr renvoyer un object en utilisant le modèle d’object nul si cela convient à vos besoins, mais il s’agit d’une discussion pour un autre thread.

204 est plus approprié. Surtout quand vous avez un système d’alerte pour vous assurer que votre site Web est sécurisé, 404 dans ce cas-là causerait de la confusion car vous ne savez pas que certaines alertes 404 sont des erreurs de gestion ou des requêtes normales mais une réponse vide.

Je dirais que ni l’un ni l’autre n’est vraiment approprié. Comme cela a été dit – par exemple, par @anneb, je pense également qu’une partie des problèmes découle de l’utilisation d’un code de réponse HTTP pour transporter un statut relatif à un service RESTful. Tout ce que le service REST doit dire à propos de son propre traitement doit être transporté au moyen de codes spécifiques REST.

1

Je dirais que si le serveur HTTP trouve un service prêt à répondre à une demande qui lui a été envoyée, il ne devrait pas répondre avec un HTTP 404 – à la fin, quelque chose a été trouvé par le serveur – à moins service qui traite la demande.

Supposons un instant l’URL suivante: http://example.com/service/return/test .

  • Le cas A est que le serveur «recherche simplement le fichier sur le système de fichiers». S’il n’est pas présent, 404 est correct. La même chose est vraie si elle demande à un service de fournir exactement ce fichier et que ce service lui indique que rien de ce nom n’existe.
  • Dans le cas B, le serveur ne fonctionne pas avec des fichiers «réels», mais en réalité, la demande est traitée par un autre service, par exemple une sorte de système de template. Ici, le serveur ne peut pas prétendre à l’existence de la ressource car elle n’en sait rien (à moins que le service ne le lui indique).

Sans réponse du service nécessitant explicitement un comportement différent, le serveur HTTP ne peut dire que 3 choses:

  • 503 si le service supposé gérer la demande n’est pas en cours d’exécution ou ne répond pas;
  • 200 sinon le serveur HTTP peut réellement satisfaire la demande – peu importe ce que le service dira plus tard;
  • 400 ou 404 pour indiquer qu’il n’y a pas un tel service (par opposition à «existe mais hors ligne») et que rien d’autre n’a été trouvé.

2

Pour revenir à la question en question: Je pense que l’approche la plus propre consisterait à ne pas utiliser de code de réponse HTTP du tout. Si le service est présent et répond, le code HTTP doit être 200. La réponse doit contenir le statut renvoyé par le service dans un en-tête distinct – ici, le service peut dire

  • REST:EMPTY par exemple s’il a été demandé de rechercher sth. et cette recherche est revenue vide;
  • REST:NOT FOUND s’il a été demandé spécifiquement pour sth. “ID-like” – être un nom de fichier ou une ressource par ID ou entrée n ° 24, etc. – et cette ressource spécifique n’a pas été trouvée (généralement, une ressource spécifique a été demandée et non trouvée);
  • REST:INVALID si une partie de la requête qui a été envoyée n’est pas reconnue par le service.

(notez que j’ai préfixé ceux-ci avec “REST:” express pour marquer le fait que ceux-ci peuvent avoir les mêmes valeurs ou les mêmes mots que les codes de réponse HTTP, mais ils sont complètement différents)

3

Revenons à l’URL ci-dessus et inspectons le cas B où le service indique au serveur HTTP qu’il ne gère pas lui-même cette requête mais le transmet à SERVICE . HTTP ne sert que ce qu’il est rendu par SERVICE , il ne sait rien de la partie return/test car elle est gérée par SERVICE . Si ce service est en cours d’exécution, HTTP devrait renvoyer 200 car il a effectivement trouvé quelque chose pour gérer la demande.

Le statut renvoyé par SERVICE (et qui, comme indiqué ci-dessus, souhaiterait voir dans un en-tête séparé) dépend de l’action attendue:

  • si return/test demande une ressource spécifique: si elle existe, retournez-la avec le statut REST:FOUND ; Si cette ressource n’existe pas, renvoyez REST:NOT FOUND ; cela pourrait être étendu pour retourner REST:GONE si nous le soaps une fois que cela a existé et ne reviendra pas, et REST:MOVED si nous soaps qu’il a disparu Hollywood
  • si return/test est considéré comme une opération de recherche ou de filtrage: si le jeu de résultats est vide, renvoyer un jeu vide dans le type demandé et un statut REST:EMPTY ; un ensemble de résultats dans le type demandé et un statut de REST:SUCCESS
  • si return/test n’est pas une opération reconnue par SERVICE : retourne REST:ERROR si elle est complètement incorrecte (par exemple, une erreur typographique telle que retrun/test ) ou REST:NOT IMPLEMENTED si elle est prévue ultérieurement.

4

Cette distinction est beaucoup plus propre que de mélanger les deux choses différentes. Cela facilitera également le débogage et le traitement sera légèrement plus complexe, voire pas du tout.

  • Si un HTTP 404 est renvoyé, le serveur me dit: «Je ne sais pas de quoi vous parlez». Bien que la partie REST de ma demande puisse être parfaitement correcte, je cherche par’Mach dans tous les mauvais endroits.
  • D’autre part, HTTP 200 et REST: ERR me dit que j’ai reçu le service mais que j’ai fait quelque chose de mal dans ma demande au service.
  • A partir de HTTP 200 et REST: EMPTY, je sais que je n’ai rien fait de mal – bon serveur, le serveur a trouvé le service, bonne demande au service – mais le résultat de la recherche est vide.

Résumé

Le problème et la discussion découlent du fait que les codes de réponse HTTP sont utilisés pour indiquer l’état d’un service dont les résultats sont servis par HTTP ou pour désigner sth. ce n’est pas dans la scope du serveur HTTP lui-même. En raison de cette divergence, il est impossible de répondre à la question et toutes les opinions font l’object de nombreuses discussions.

L’état d’une demande traitée par un service et non le serveur HTTP ne devrait pas (RFC 6919) être donné par un code de réponse HTTP. Le code HTTP SHOULD (RFC 2119) ne contient que les informations que le serveur HTTP peut donner de sa propre scope: à savoir, si le service a été trouvé ou non pour traiter la demande.

Au lieu de cela, une manière différente DEVRAIT être utilisée pour indiquer à un consommateur l’état de la demande au service qui traite réellement la demande. Ma proposition est de le faire via un en-tête spécifique. Dans l’idéal, le nom de l’en-tête et son contenu respectent une norme qui facilite le travail des consommateurs avec ces réponses.

Encodez le contenu de la réponse avec un enum commun qui permet au client de l’activer et de la logique de la fourche en conséquence. Je ne sais pas comment votre client pourrait distinguer la différence entre une “donnée non trouvée” 404 et une “ressource Web non trouvée” 404? Vous ne voulez pas que quelqu’un consulte l’utilisateur Z / 9 et demande au client de se demander si la demande était valide, mais aucune donnée n’a été renvoyée.

Pourquoi ne pas utiliser 410? Il suggère que la ressource demandée n’existe plus et que le client ne doit jamais faire de demande pour cette ressource, dans votre cas, les users/9 .

Vous pouvez trouver plus de détails sur 410 ici: https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html