Je construis un serveur qui permet aux clients de stocker des objets. Ces objets sont entièrement construits côté client, avec des ID d'objet qui sont permanents pour toute la durée de vie de l'objet.
J'ai défini l'API pour que les clients puissent créer ou modifier des objets en utilisant PUT:
PUT /objects/{id} HTTP/1.1
...
{json representation of the object}
Le {id} est l'ID d'objet, il fait donc partie de l'URI de demande.
Maintenant, j'envisage également d'autoriser les clients à créer l'objet à l'aide de POST:
POST /objects/ HTTP/1.1
...
{json representation of the object, including ID}
Étant donné que POST est conçu comme une opération "ajouter", je ne sais pas quoi faire au cas où l'objet est déjà là. Dois-je traiter la demande comme une demande de modification ou dois-je renvoyer un code d'erreur (lequel)?
Réponses:
Mon sentiment est
409 Conflict
le plus approprié, cependant, rarement vu dans la nature bien sûr:la source
HTTP 409
avec un en-Location
tête pointant vers la ressource existante / conflictuelle.Selon la RFC 7231 , un 303 See Other PEUT être utilisé si le résultat du traitement d'un POST serait équivalent à une représentation d'une ressource existante .
la source
Personnellement, je vais avec l'extension WebDAV
422 Unprocessable Entity
.Selon RFC 4918
la source
422
me semble étrange ...Tout dépend du contexte , et aussi de qui est responsable du traitement des doublons dans les demandes (serveur ou client ou les deux)
Si le serveur pointe simplement le doublon , regardez 4xx:
Pour la gestion implicite des doublons, regardez 2XX:
si le serveur doit renvoyer quelque chose , regardez 3XX:
lorsque le serveur est capable de pointer la ressource existante, cela implique une redirection.
Si ce qui précède ne suffit pas, il est toujours recommandé de préparer un message d'erreur dans le corps de la réponse.
la source
Tard dans le jeu peut-être mais je suis tombé sur ce problème sémantique en essayant de créer une API REST.
Pour développer un peu la réponse de Wrikken, je pense que vous pouvez utiliser soit
409 Conflict
ou403 Forbidden
selon la situation - en bref, utiliser une erreur 403 lorsque l'utilisateur ne peut absolument rien faire pour résoudre le conflit et terminer la demande (par exemple, il ne peut pas envoyer deDELETE
demande de suppression explicite de la ressource), ou utilisez 409 si quelque chose peut être fait.De nos jours, quelqu'un dit "403" et un problème d'autorisations ou d'authentification vient à l'esprit, mais la spécification dit que c'est essentiellement le serveur qui dit au client qu'il ne va pas le faire, ne le demandez plus, et voici pourquoi le client ne devrait pas 't.
Pour ce qui est de
PUT
vsPOST
...POST
doit être utilisé pour créer une nouvelle instance d'une ressource lorsque l'utilisateur n'a aucun moyen de créer ou ne doit pas créer un identifiant pour la ressource.PUT
est utilisé lorsque l'identité de la ressource est connue.la source
POST
demande (lorsqu'elle est utilisée correctement), car elle indique qu'elle doit être renvoyée en cas de conflit avec la ressource cible . Étant donné que la ressource cible n'a pas encore été publiée, elle ne peut pas être en conflit, et donc répondre avec409 Conflict
n'a aucun sens.POST
, en fait, je déduirais le contraire parce que "les conflits sont plus susceptibles de se produire en réponse à une demande PUT." semble indiquer que d'autres méthodes de demande peuvent également utiliser ce code. De plus, «le corps de la réponse doit inclure suffisamment d'informations pour que l'utilisateur reconnaisse la source du conflit. Idéalement, l'entité de réponse devrait inclure suffisamment d'informations pour que l'utilisateur ou l'agent utilisateur puisse résoudre le problème; cependant, cela pourrait ne pas être possible et est pas nécessaire . " ( webdav.org/specs/rfc2616.html#status.409 )"302 Found" me semble logique. Et le RFC 2616 dit qu'il peut être répondu pour d'autres demandes que GET et HEAD (et cela inclut sûrement POST)
Mais cela permet toujours au visiteur d'accéder à cette URL pour obtenir cette ressource "Trouvé", par le RFC. Pour qu'il aille directement à l'URL réelle "trouvée", il faut utiliser "303 See Other", ce qui est logique, mais force un autre appel à GET son URL suivante. Du bon côté, ce GET est cacheable.
Je pense que j'utiliserais "303 See Other" . Je ne sais pas si je peux répondre avec la "chose" trouvée dans le corps, mais je voudrais le faire pour enregistrer un aller-retour sur le serveur.
MISE À JOUR: Après avoir relu la RFC, je pense toujours qu'un code "4XX + 303 trouvé" inexistant devrait être le bon. Cependant, le «conflit 409» est le meilleur code de réponse existant (comme indiqué par @Wrikken), peut-être comprenant un en-tête Location pointant vers la ressource existante.
la source
Je ne pense pas que tu devrais faire ça.
Le POST est, comme vous le savez, pour modifier la collection et il est utilisé pour CRÉER un nouvel élément. Donc, si vous envoyez l'identifiant (je pense que ce n'est pas une bonne idée), vous devez modifier la collection, c'est-à-dire modifier l'élément, mais c'est déroutant.
Utilisez-le pour ajouter un élément, sans identifiant. C'est la meilleure pratique.
Si vous souhaitez capturer une contrainte UNIQUE (pas l'id), vous pouvez répondre 409, comme vous pouvez le faire dans les requêtes PUT. Mais pas l'ID.
la source
J'irais avec
422 Unprocessable Entity
, qui est utilisé lorsqu'une demande n'est pas valide mais que le problème n'est pas lié à la syntaxe ou à l'authentification.Comme argument contre d'autres réponses, utiliser n'importe quel
4xx
code non- erreur impliquerait que ce n'est pas une erreur client, et c'est évidemment le cas. Utiliser un4xx
code sans erreur pour représenter une erreur client n'a tout simplement aucun sens.Il semble que ce
409 Conflict
soit la réponse la plus courante ici, mais, selon la spécification, cela implique que la ressource existe déjà et que les nouvelles données que vous lui appliquez sont incompatibles avec son état actuel. Si vous envoyez unPOST
demande, avec, par exemple, un nom d'utilisateur déjà pris, il n'est pas réellement en conflit avec la ressource cible, car la ressource cible (la ressource que vous essayez de créer) n'a pas encore été publiée. Il s'agit d'une erreur spécifique au contrôle de version, en cas de conflit entre la version de la ressource stockée et la version de la ressource demandée. C'est très utile à cet effet, par exemple lorsque le client a mis en cache une ancienne version de la ressource et envoie une demande basée sur cette version incorrecte qui ne serait plus conditionnellement valide. "Dans ce cas, la représentation de la réponse contiendrait probablement des informations utiles pour fusionner les différences en fonction de l'historique des révisions." La demande de création d'un autre utilisateur avec ce nom d'utilisateur n'est tout simplement pas traitable, n'ayant rien à voir avec le contrôle de version.Pour mémoire, 422 est également le code d'état que GitHub utilise lorsque vous essayez de créer un référentiel avec un nom déjà utilisé.
la source
Je pense que pour REST, il suffit de prendre une décision sur le comportement de ce système particulier, auquel cas, je pense que la "bonne" réponse serait l'une des quelques réponses données ici. Si vous voulez que la demande s'arrête et se comporte comme si le client avait fait une erreur qu'il devait corriger avant de continuer, utilisez 409. Si le conflit n'est vraiment pas si important et que vous souhaitez continuer la demande, répondez en redirigeant le client à l'entité trouvée. Je pense que les API REST appropriées devraient rediriger (ou au moins fournir l'en-tête d'emplacement) vers le point de terminaison GET pour cette ressource après un POST de toute façon, donc ce comportement donnerait une expérience cohérente.
EDIT: Il convient également de noter que vous devriez envisager un PUT puisque vous fournissez l'ID. Ensuite, le comportement est simple: "Je me fiche de ce qu'il y a en ce moment, mettez cette chose là." Autrement dit, s'il n'y a rien, il sera créé; si quelque chose est là, il sera remplacé. Je pense qu'un POST est plus approprié lorsque le serveur gère cet ID. Séparer les deux concepts vous indique essentiellement comment y faire face (c'est-à-dire que PUT est idempotent donc il devrait toujours fonctionner aussi longtemps que la charge utile est validée, POST crée toujours, donc s'il y a une collision d'ID, alors un 409 décrirait ce conflit) .
la source
POST
demande (lorsqu'elle est utilisée correctement), car elle indique qu'elle doit être renvoyée en cas de conflit avec la ressource cible . Étant donné que la ressource cible n'a pas encore été publiée, elle ne peut pas être en conflit, et donc répondre avec409 Conflict
n'a aucun sens.PUT
.Un autre traitement potentiel consiste à utiliser PATCH après tout. Un PATCH est défini comme quelque chose qui change l'état interne et n'est pas limité à l'ajout.
PATCH résoudrait le problème en vous permettant de mettre à jour des éléments déjà existants. Voir: RFC 5789: PATCH
la source
Pourquoi pas un 202 accepté ? C'est une demande OK (200s), il n'y a pas eu d'erreurs client (400s) en soi.
De 10 définitions de code d'état :
... parce qu'il n'avait pas besoin d'être terminé, car il existait déjà. Le client ne sait pas qu'il existait déjà, il n'a rien fait de mal.
Je me penche sur le lancement d'un 202 et le retour d'un contenu similaire à ce qu'un GET
/{resource}/{id}
aurait retourné.la source
Je suis tombé sur cette question tout en vérifiant le code correct pour l'enregistrement en double.
Excusez mon ignorance mais je ne comprends pas pourquoi tout le monde ignore le code "300" qui dit clairement "choix multiple" ou "ambigu"
À mon avis, ce serait le code parfait pour construire un système non standard ou particulier pour votre propre usage. Je peux me tromper aussi!
https://tools.ietf.org/html/rfc7231#section-6.4.1
la source
Il est plus probable
400 Bad Request
Comme la demande contient une valeur en double (valeur qui existe déjà), elle peut être perçue comme une erreur client. Besoin de modifier la demande avant le prochain essai.
En considérant ces faits, nous pouvons conclure que HTTP STATUS 400 Bad Request.
la source
Qu'en est-il de 208 - http://httpstatusdogs.com/208-already-reported ? Est-ce une option?
À mon avis, si la seule chose est une ressource répétée, aucune erreur ne devrait être soulevée. Après tout, il n'y a aucune erreur ni côté client ni côté serveur.
la source
Dans votre cas, vous pouvez utiliser
409 Conflict
Et si vous voulez vérifier un autre
HTTPs
code d'état de la liste ci-dessous1 ×umed Informatif
2 × × Succès
Redirection 3 ×
Erreur client 4 ×umed
Erreur du serveur 5 ×umed
la source