Quel code de réponse d'état HTTP dois-je utiliser s'il manque un paramètre obligatoire dans la demande?

Réponses:

388

Le statut 422 semble le plus approprié en fonction de la spécification .

Le code d'état 422 (entité non traitable) signifie que le serveur comprend le type de contenu de l'entité de demande (donc un code d'état 415 (type de support non pris en charge) est inapproprié), et la syntaxe de l'entité de demande est correcte (donc 400 (mauvaise demande) ) le code d'état est inapproprié) mais n'a pas pu traiter les instructions contenues. Par exemple, cette condition d'erreur peut se produire si un corps de requête XML contient des instructions XML bien formées (c'est-à-dire syntaxiquement correctes) mais sémantiquement erronées.

Ils déclarent que le XML mal formé est un exemple de mauvaise syntaxe (appelant un 400). Une chaîne de requête mal formée semble analogue à cela, donc 400 ne semble pas approprié pour une chaîne de requête bien formée à laquelle il manque un paramètre.

UPDATE @DavidV souligne correctement que cette spécification est pour WebDAV, pas pour le noyau HTTP. Mais certaines API non WebDAV populaires utilisent de toute façon 422, faute d'un meilleur code d'état ( voir ceci ).

Kelvin
la source
2
IMO J'utiliserais ceci pour quand la valeur dans la chaîne de requête était incorrecte, pas quand il y avait une valeur supplémentaire ou une valeur manquante. c'est à dire. Attendre un e-mail et sa valeur est '123123'
Derek Litz
2
J'ai tendance à considérer les paramètres GET et POST comme la signature de méthode du chemin URL, donc 404 est logique pour moi. Dans une API RESTful destinée à la consommation publique, il est prudent de renvoyer les paramètres manquants / supplémentaires. Dans le contexte d'une URL, les paramètres de la chaîne de requête sont généralement importants pour identifier une ressource et les paramètres supplémentaires ou manquants représentent une ressource qui n'existe pas, sans aucune hypothèse. Bien sûr, il existe des compromis avec la robustesse en étant explicites, et les paramètres facultatifs rendent une ressource potentiellement tout aussi vulnérable aux erreurs silencieuses. Ensuite, il y a l'utilisabilité ...
Derek Litz
13
La spécification référencée est pour WebDAV et n'est pas la spécification standard HTTP.
David V
1
@Kelvin Merci d'avoir signalé ce billet de blog. Il est utile de voir que Twitter, par exemple, utilise 422. Je pense que la réponse pourrait être meilleure si vous précisez que la spécification est WebDAV sur la première ligne. Quand j'ai lu votre réponse pour la première fois, je pensais que vous vouliez dire la spécification standard HTTP jusqu'à ce que je suive le lien.
David V
3
Cela vaut la peine d'être lu: bennadel.com/blog/… Je n'utiliserais pas 422 pour param manquant non plus. Je pense que 400c'est plus approprié.
Zelphir Kaltstahl
184

Je ne suis pas sûr qu'il existe une norme définie, mais j'aurais utilisé 400 Bad Request , que la dernière spécification HTTP (de 2014) documente comme suit :

6.5.1. 400 Mauvaise demande

Le code d'état 400 (Bad Request) indique que le serveur ne peut pas ou ne traitera pas la demande en raison de quelque chose qui est perçu comme une erreur client (par exemple, une syntaxe de demande incorrecte, un cadrage de message de demande invalide ou un routage de demande trompeur).

Gert Grenander
la source
65
400 Bad Requestest destiné à indiquer des problèmes au niveau du protocole, pas des erreurs sémantiques. Si nous allons détourner les codes d'état HTTP pour indiquer des erreurs au niveau de l'application (plutôt qu'au niveau du protocole), pourquoi ne pas aller jusqu'au bout et simplement utiliser 412?
Matt Zukowski
36
L'implémentation OAuth 1.0 de Google est d'accord avec cette réponse. Une réponse 400 est donnée lorsque les paramètres POST sont manquants ou non pris en charge: code.google.com/apis/accounts/docs/OAuth_ref.html
Tom
1
@ matt-zukowski: "412: La condition préalable donnée dans un ou plusieurs des champs d'en-tête de demande est évaluée à false lorsqu'elle a été testée sur le serveur." from RFC2616 - S'il s'agit d'un POST, les paramètres se trouvent dans le corps de la demande et non dans les champs d'en-tête de demande. Techniquement, la méthode GET envoie ses paramètres dans les en-têtes de demande, mais je préfère avoir une certaine cohérence à la place?
toong
6
@MattZukowski 400 est un code d'état au niveau de l'application. Si vous regardez la reformulation dans la version préliminaire de la RFC 7231, vous le verrez. Malheureusement, le libellé de la dernière version n'est pas aussi clair car l'auteur des dernières modifications a également inventé 422.
Darrel Miller
9
@DarrelMiller a raison ( lien direct ): "Le code d'état 400 (Bad Request) indique que le serveur ne peut pas ou ne traitera pas la demande en raison de quelque chose qui est perçu comme une erreur client (par exemple, syntaxe de demande mal formée, message de demande non valide cadrage ou routage de demande trompeur). " En fonction des attentes sémantiques et d'extensibilité (sera-t-il possible un jour d'émettre une requête sans le paramètre?) Alors seuls 400 et 404 semblent appropriés en HTTP standard. Sinon, inventez un nouveau code pour votre API, mais ne surchargez pas la sémantique.
TNE
31

L' API WCF dans .NET gère les paramètres manquants en renvoyant une HTTP 404erreur «Endpoint Not Found», lors de l'utilisation de webHttpBinding .

Cela 404 Not Foundpeut avoir un sens si vous considérez le nom de votre méthode de service Web avec sa signature de paramètre. Autrement dit, si vous exposez une méthode de service Web LoginUser(string, string)et que vous en faites la demande LoginUser(string), cette dernière n'est pas trouvée.

Fondamentalement, cela signifie que la méthode de service Web que vous appelez, ainsi que la signature de paramètre que vous avez spécifiée, est introuvable.

10.4.5 404 introuvable

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

Le 400 Bad Request, comme l'a suggéré Gert , reste un code de réponse valide, mais je pense qu'il est normalement utilisé pour indiquer des problèmes de niveau inférieur. Elle pourrait facilement être interprétée comme une requête HTTP mal formée, peut-être des en-têtes HTTP manquants ou invalides, ou similaire.

10.4.1 400 Mauvaise requête

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

Daniel Vassallo
la source
C'est ce que fait CherryPy par défaut.
Derek Litz
Qu'en est-il de la gestion d'une demande de publication lorsque vous acceptez un modèle et qu'une partie du modèle est manquante? Dans ce cas, vous n'obtenez pas un 404. Au lieu de cela, vous obtenez un modèle qui n'est pas valide si je ne me trompe pas et vous devez décider quoi faire maintenant.
Shane Courtrille
1
Cette interprétation semble être un tronçon et exprime un RPC plutôt qu'un pov REST. L'URI est l'identifiant, il existe et a été trouvé. Ce qui est envoyé dans le corps ne fait pas partie de l'identifiant de ressource. 422 est plus approprié.
Jonah
404 est la bonne réponse, allez juste éditer quelques URL sur le web pour trouver le consensus!
jenson-button-event
8

Vous pouvez envoyer un code 400 Bad Request. C'est l'un des codes d'état 4xx à usage plus général, vous pouvez donc l'utiliser pour signifier ce que vous voulez: le client envoie une demande qui manque les informations / paramètres dont votre application a besoin pour la traiter correctement.

BoltClock
la source
7

Dans l'un de nos projets API, nous décidons de définir un statut 409 pour une demande, lorsque nous ne pouvons pas le remplir à 100% en raison d'un paramètre manquant.

Le code d'état HTTP "409 Conflict" a été pour nous un bon essai car sa définition nécessite d'inclure suffisamment d'informations pour que l'utilisateur reconnaisse la source du conflit.

Référence: w3.org/Protocols/

Ainsi, parmi d'autres réponses telles que 400 ou 404, nous avons choisi 409 pour imposer la nécessité de parcourir certaines notes de la demande, utiles pour configurer une nouvelle et correcte demande.

Quoi qu'il en soit, notre cas était particulier, car nous devons envoyer des données la veille si la demande n'était pas complètement correcte, et nous devons obliger le client à lire le message et à comprendre ce qui n'allait pas dans la demande.

En général, si nous n'avons que quelques paramètres manquants, nous optons pour un 400 et un tableau de paramètres manquants. Mais lorsque nous devons envoyer plus d'informations, comme un message de cas particulier et que nous voulons être plus sûrs que le client s'en occupera, nous envoyons un 409

gabrielem
la source
2
C'est tout à fait faux. 409 est destiné aux problèmes de concurrence, comme @ MaximeGélinas le fait remarquer OU dans les situations où une ressource est déjà présente et où les doublons ne sont pas autorisés.
gimlichael
Selon la spécification, "Le code d'état 409 (Conflit) indique que la demande n'a pas pu aboutir en raison d'un conflit avec l'état actuel de la ressource cible." . L'utiliser pour un paramètre manquant est tout simplement faux; c'est une erreur totalement différente.
Mark Amery
5

J'utilise généralement 422 (entité non traitable) si quelque chose dans les paramètres requis ne correspond pas à ce que le point de terminaison API exigeait (comme un mot de passe trop court), mais pour un paramètre manquant, j'opterais pour 406 (inacceptable).

Elad Meidar
la source
8
Eh bien, 406 Inacceptable est utilisé avec l'en-tête Accept (si le serveur ne peut pas envoyer de réponse, le client comprendra). "La ressource identifiée par la demande est uniquement capable de générer des entités de réponse dont les caractéristiques de contenu ne sont pas acceptables selon les en-têtes d'acceptation envoyés dans la demande." . Je suis coincé avec 422 car il n'y a pas de "bon" choix avec les spécifications actuelles: - /
JakubKnejzlik
Utiliser 406 pour cela est faux. Un code 406 ne signifie pas que la demande n'était pas acceptable; cela signifie que vous ne pouvez pas satisfaire la demande, car les réponses que vous pouvez servir sont celles que le client trouverait inacceptables, sur la base des en-têtes Accept qu'il a envoyés dans la demande. (Par exemple, la demande incluse Accept-Language: de, indiquant qu'il n'acceptera que les réponses en allemand, mais les seules versions du document demandé disponibles sur votre serveur sont en anglais ou en français.) L'utiliser pour indiquer un paramètre manquant dans la demande est incorrect, selon la définition dans spec.
Mark Amery
3

Pour ceux qui sont intéressés, Spring MVC (3.x au moins) renvoie un 400 dans ce cas, ce qui me semble faux.

J'ai testé plusieurs URL Google (accounts.google.com) et supprimé les paramètres requis, et ils retournent généralement un 404 dans ce cas.

Je copierais Google.

Neromancer
la source
18
Parce que Google le fait ne signifie pas automatiquement que Google le fait correctement!
rve
4
Je suis d'accord, pas nécessairement «juste» mais parfois ce qui est bien et ce qui est sensé sont deux choses différentes. Quoi qu'il en soit .. jusqu'au lecteur :)
Neromancer
Certaines API Google renvoient un 400, par exemple github.com/google/google-api-nodejs-client/issues/404
Dennis
ce qui est faux (et pourquoi le mvc du printemps n'est pas compatible avec jax-rs)
jenson-button-event
3

On pourrait faire valoir que a 404 Not Founddevrait être utilisé car la ressource spécifiée est introuvable.

Rayon
la source
3
Il s'agit du comportement par défaut de Java JAX-RS lorsqu'un paramètre de requête ne peut pas être converti en le type de données approprié. Je ne suis pas d'accord cependant. La ressource a été trouvée: les paramètres de requête servent à filtrer la ressource et l'un des filtres a été fourni avec une valeur inacceptable. Je pense que cela correspond à 422 entité non traitable la plus proche, et à 400 deuxième requête incorrecte la plus proche.
Ryan
c'est le comportement par défaut de jax-rs car c'est le bon comportement!
jenson-button-event
L'utilisation d'un 404 est raisonnable lorsque le paramètre de chaîne de requête est destiné à identifier une ressource, une valeur a été donnée, mais cette valeur ne correspond pas à une ressource qui existe - par exemple, si vous demandez example.com/show-user -profile? user_id = 123 et l'utilisateur 123 n'existe pas. Mais ce n'est pas ce que cette question demandait; il s'agissait du scénario où un paramètre requis est entièrement omis. Je ne vois pas comment cela correspond à une ressource spécifiée non trouvée.
Mark Amery
2

J'utilise souvent une erreur interdite 403. Le raisonnement est que la demande a été comprise, mais je ne vais pas faire comme demandé (parce que les choses vont mal). L'entité de réponse explique ce qui ne va pas, donc si la réponse est une page HTML, les messages d'erreur sont dans la page. S'il s'agit d'une réponse JSON ou XML, les informations d'erreur s'y trouvent.

De rfc2616 :

10.4.4 403 Interdit

Le serveur a compris la demande, mais refuse de la satisfaire.
L'autorisation n'aidera pas et la demande NE DEVRAIT PAS être répétée.
Si la méthode de demande n'était pas HEAD et que le serveur souhaite rendre
public pourquoi la demande n'a pas été satisfaite, il DEVRAIT décrire la raison du refus dans l'entité. Si le serveur ne souhaite pas mettre ces informations à la disposition du client, le code d'état 404
(Not Found) peut être utilisé à la place.

cdeszaq
la source
4
Cela semble bon au départ, bien que j'associe naturellement cela à des erreurs d'authentification ou d'autorisation. En outre, la spécification fait allusion à cela où elle dit "si le serveur ne souhaite pas mettre ces informations à la disposition du client". De plus, le 404 pourrait être une meilleure option. Je me dirigerais vers un 404 ou 400 qu'un 403.
tonyhb
21
C'est une idée terrible, même si elle est techniquement valable. 403 est universellement utilisé pour les réponses d'échec d'authentification, et vous confondrez l'enfer de vos clients si vous essayez de l'utiliser pour indiquer des erreurs de paramètres. Par exemple, Twitter le fait - 403 est utilisé à la fois lorsque vous fournissez des informations d'identification OAuth invalides et lorsqu'il y a quelque chose de sémantiquement incorrect avec votre demande - et c'est une source constante de confusion pour les clients API.
Matt Zukowski
1
@MattZukowski et bien c'est tout simplement faux. La spécification dit Authorization will not help, donc Twitter ne devrait pas envoyer cela pour les informations d'identification OAuth non valides.
torvin
@torvin Twitter devrait plutôt envoyer un 401 Unauthorized. Cependant, vous pouvez comprendre pourquoi ils ne le font pas si vous regardez les descriptions des documents MDN de ces deux codes, qui sont très similaires.
Agi Hammerthief
-1

Juste pour utiliser ASP.NET Core comme référence ou exemple, ASP.NET Core vous permet d'échafauder un contrôleur avec des actions, voici à quoi ressemble l'action "Détails".

    // GET: Cars/Details/5
    public async Task<IActionResult> Details(int? id)
    {
        if (id == null)
        {
            return NotFound();
        }

        var car = await _context.Cars.FirstOrDefaultAsync(m => m.CarId == id);
        if (car == null)
        {
            return NotFound();
        }

        return View(car);
    }

Si le paramètre idn'est pas défini, il renvoie 404 Not Found.

Fred
la source
-5

Renvoyer un 404 - ce qui signifie que la ressource est introuvable.

Essayez de modifier l'URL d'un site contenant un identifiant. J'en ai essayé quelques-uns:

  • problème de dépôt gitub
  • page de confluence
  • vue du produit amazon
  • liste ebay
  • article de presse bbc

Tous renvoient 404, imo parce que ces développeurs interprètent correctement la norme, ce que la réponse ici et beaucoup d'autres ne sont pas!

événement jenson-button
la source
1
Je crois que la plupart des développeurs définissent le "paramètre" comme l'une des paires nom / valeur dans une chaîne de requête ou un corps POST de formulaire. Une demande de problème de dépôt Github ne contient pas cela.
Kelvin
@Kelvin we devs inclut également des paramètres de chemin dans la liste. si TOUT paramètre d'url est obligatoire, représente l'emplacement d'une ressource et n'est pas inclus, alors 404 doit être retourné. Cela exclut le requestBody.
jenson-button-event
-6

J'irais avec un 403.

De RFC 2616 - Hypertext Transfer Protocol - HTTP / 1.1

403 Interdit

Le serveur a compris la demande, mais refuse de la satisfaire. L'autorisation n'aidera pas et la demande NE DEVRAIT PAS être répétée. Si la méthode de demande n'était pas HEAD et que le serveur souhaite rendre public pourquoi la demande n'a pas été satisfaite, il DEVRAIT décrire la raison du refus dans l'entité. Si le serveur ne souhaite pas mettre ces informations à la disposition du client, le code d'état 404 (Not Found) peut être utilisé à la place.

Vous devez décrire la raison de l'échec dans votre réponse. Si vous préférez ne pas le faire, utilisez simplement le 404.

Francisco Costa
la source
3
downvoted car il s'agit d'une réponse en double. Pensez à ajouter votre dernière phrase en tant que commentaire à l'ancienne réponse qui propose d'utiliser 403
utilisateur