Question Codes d'état HTTP REST pour une validation échouée ou un doublon non valide


Je construis une application avec une API basée sur REST et j'en suis arrivé au point où je spécifie des codes d'état pour chaque requête.

Quel code d'état dois-je envoyer pour les demandes qui échouent à la validation ou lorsqu'une demande tente d'ajouter un doublon dans ma base de données?

J'ai regardé à travers http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html mais aucun d'eux ne semble juste.

Existe-t-il une pratique courante lors de l'envoi de codes d'état?


653
2017-07-20 13:03


origine


Réponses:


Pour l'échec de validation d'entrée: 400 Mauvaise demande + votre description facultative. Ceci est suggéré dans le livre "Services Web RESTful". Pour double soumettre: 409 Conflit


Mise à jour juin 2014

La spécification pertinente était utilisée RFC2616, qui a donné l'utilisation de 400 (Bad Request) plutôt étroitement

La requête n'a pas pu être comprise par le serveur en raison d'une syntaxe mal formée

Donc ça pourrait ont été argumentés qu'il était inapproprié pour les erreurs sémantiques. Mais plus maintenant; depuis juin 2014, la norme pertinente RFC 7231, qui remplace le précédent RFC2616, donne l'usage de 400 (Mauvaise demande) plus largement

le serveur ne peut pas ou      ne traitera pas la demande en raison de quelque chose qui est perçu comme      une erreur de client


618
2017-07-20 13:05



  • Echec de la validation: 403 Interdit ("Le serveur a compris la requête, mais refuse de la remplir"). Contrairement à l'opinion populaire, RFC2616 ne dit pas "403 est seulement destiné à l'authentification échouée", mais "403: Je sais ce que vous voulez, mais je ne le ferai pas". Cette condition peut ou peut ne pas être due à l'authentification.
  • Essayer d'ajouter un doublon: 409 Conflit ("La requête n'a pas pu aboutir en raison d'un conflit avec l'état actuel de la ressource.")

Vous devriez certainement donner une explication plus détaillée dans les en-têtes de réponse et / ou le corps (par exemple avec un en-tête personnalisé - X-Status-Reason: Validation failed).


249
2017-07-20 13:24



je recommande code d'état 422, "Entité non traitable".

11.2. 422 Entité non traitable

Le code d'état 422 (Entité non traitable) signifie que le serveur comprend le type de contenu de l'entité de requête (un code d'état 415 (Unsupported Media Type) est inapproprié) et la syntaxe de l'entité de requête est correcte (400 ) 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.


167
2017-07-20 14:56



200 300, 400, 500 sont tous très génériques. Si vous voulez générique, 400 est OK.

422 est utilisé par un nombre croissant d'API et est même utilisé par Rails dès sa sortie de la boîte.

Quel que soit le code d'état que vous choisissez pour votre API, quelqu'un ne sera pas d'accord. Mais je préfère 422 parce que je pense que '400 + text status' est trop générique. De plus, vous n'utilisez pas un analyseur compatible JSON. en revanche, un 422 avec une réponse JSON est très explicite, et une grande quantité d'informations d'erreur peut être transmise.

Parlant de la réponse JSON, j'ai tendance à standardiser sur la réponse d'erreur Rails pour ce cas, qui est:

{
    "errors" :
    { 
        "arg1" : ["error msg 1", "error msg 2", ...]
        "arg2" : ["error msg 1", "error msg 2", ...]
    }
}

Ce format est parfait pour la validation de formulaire, que je considère comme le cas le plus complexe à prendre en charge en termes de «richesse de rapports d'erreurs». Si votre structure d'erreur est celle-ci, elle traitera probablement tous vos besoins de rapports d'erreurs.


69
2018-04-04 17:40



Un doublon dans la base de données devrait être un 409 CONFLICT.

Je recommande d'utiliser 422 UNPROCESSABLE ENTITY pour les erreurs de validation.

Je donne une explication plus longue des codes 4xx ici: http://parker0phil.com/2014/10/16/REST_http_4xx_status_codes_syntax_and_sematics/


27
2017-10-16 23:05



200

Ugh ... (309, 400, 403, 409, 415, 422) ... beaucoup de réponses essayant de deviner, argumenter et normaliser quel est le meilleur code retour pour un demande http réussie mais un appel de repos raté.

C'est faux pour mélanger les codes de protocole HTTP et les résultats REST.

Cependant, j'ai vu de nombreuses implémentations les mélangeant, et beaucoup de développeurs peuvent ne pas être d'accord avec moi.

Les codes de retour HTTP sont liés à HTTP Request lui-même. Un appel REST est effectué à l'aide d'une requête de protocole de transfert hypertexte et fonctionne à un niveau inférieur à la méthode REST invoquée elle-même. REST est un concept / approche, et sa sortie est un affaires / logique résultat, tandis que le code de résultat HTTP est un transport un.

Par exemple, renvoyer "404 Not found" lorsque vous appelez / users / est confus, car cela peut signifier:

  • L'URI est incorrecte (HTTP)
  • Aucun utilisateur trouvé (REST)

"403 Interdit / Accès refusé" peut signifier:

  • Autorisation spéciale requise. Les navigateurs peuvent le gérer en demandant à l'utilisateur / mot de passe. (HTTP)
  • Mauvaises permissions d'accès configurées sur le serveur. (HTTP)
  • Vous devez être authentifié (REST)

Et la liste peut continuer avec '500 Erreur de serveur "(une erreur HTTP Apache / Nginx levée ou une erreur de contrainte métier dans REST) ​​ou d'autres erreurs HTTP etc ...

À partir du code, il est difficile de comprendre quelle était la raison de l'échec, une défaillance HTTP (transport) ou une défaillance REST (logique).

Si la requête HTTP a été physiquement effectuée avec succès, elle devrait toujours renvoie le code 200, quel que soit le ou les enregistrements trouvés ou non. Parce que la ressource URI est a trouvé et a été géré par le serveur http. Oui, il peut retourner un ensemble vide. Est-il possible de recevoir une page web vide avec 200 comme résultat http, non?

Au lieu de cela, vous pouvez renvoyer 200 codes HTTP avec quelques options:

  • Objet "error" dans le résultat JSON si quelque chose ne va pas
  • Tableau JSON vide / objet si aucun enregistrement trouvé
  • Un résultat booléen / drapeau de succès en combinaison avec les options précédentes pour une meilleure manipulation.

En outre, certains fournisseurs d'accès Internet peuvent intercepter vos demandes et vous renvoyer un code http 404. Cela ne signifie pas que vos données ne sont pas trouvées, mais c'est quelque chose qui ne va pas au niveau du transport.

De Wiki:

En juillet 2004, le fournisseur de télécommunications britannique BT Group a déployé le Cleanfeed   système de blocage de contenu, qui renvoie une erreur 404 à toute demande de   contenu identifié comme potentiellement illégal par Internet Watch   Fondation. D'autres FAI retournent une erreur HTTP 403 "interdite" dans le même   conditions. La pratique d'employer de fausses erreurs 404 comme moyen de   la censure dissimulée a également été signalée en Thaïlande et en Tunisie. Dans   Tunisie, où la censure était sévère avant la révolution de 2011,   les gens sont devenus conscients de la nature des fausses erreurs 404 et créé   un personnage imaginaire nommé "Ammar 404" qui représente "l'invisible   censurer".

Pourquoi ne pas simplement répondre avec quelque chose comme ça?

{
  "result": false,
  "error": {"code": 102, "message": "Validation failed: Wrong NAME."}
}

Google renvoie toujours 200 comme code d'état dans son API de géocodage, même si la demande échoue logiquement: https://developers.google.com/maps/documentation/geocoding/intro#StatusCodes


7
2017-09-23 12:42



Code d'état 304 non modifié ferait également une réponse acceptable à une demande en double. Ceci est similaire au traitement d'un en-tête de If-None-Match en utilisant une balise d'entité.

À mon avis, la réponse de @ Piskvor est le choix le plus évident pour ce que je perçois comme l'intention de la question initiale, mais j'ai une alternative qui est également pertinente.

Si vous souhaitez traiter une demande en double comme un avertissement ou une notification plutôt qu'une erreur, un code d'état de réponse 304 Non modifié et Content-Location l'en-tête identifiant la ressource existante serait tout aussi valide. Lorsque l'intention est simplement de s'assurer qu'une ressource existe, une demande en double ne serait pas une erreur mais une confirmation. La requête n'est pas fausse, mais est simplement redondante, et le client peut se référer à la ressource existante.

En d'autres termes, la requête est bonne, mais comme la ressource existe déjà, le serveur n'a pas besoin d'effectuer de traitement supplémentaire.


6
2018-03-17 19:14



L'adaptateur ActiveRecord d'Ember-Data attend 422 UNPROCESSABLE ENTITY à renvoyer du serveur. Donc, si votre client est écrit dans Ember.js, vous devriez utiliser 422. Seulement alors DS.Errors sera rempli avec les erreurs retournées. Vous pouvez bien sûr changer 422 en n'importe quel autre code dans votre adaptateur.


6
2017-12-03 22:17