Code de réponse HTTP pour le POST lorsque la ressource existe déjà

je construis un serveur qui permet aux clients de stocker des objets. Ces objets sont entièrement construits du côté du client, avec des identificateurs d'objet qui sont permanents pendant toute la durée de vie de l'objet.

j'ai défini L'API de sorte 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'identifiant de l'objet, il fait donc partie de L'URI-Request.

maintenant, je pense aussi permettre aux clients de créer l'objet utilisant POST:

POST /objects/ HTTP/1.1
...

{json representation of the object, including ID}

puisque POST signifie "ajouter" opération, Je ne suis pas sûr de ce qu'il faut faire au cas où l'objet est déjà là. Dois-je traiter la requête comme une requête de modification ou dois-je retourner un code d'erreur (lequel)?

581
demandé sur vmj 2010-09-30 01:26:13

15 réponses

Mon sentiment est 409 Conflict est le plus approprié, cependant, que l'on voit rarement dans la nature de la formation:

la demande n'a pu être traitée en raison d'un conflit avec l'état actuel de la ressource. Ce code n'est autorisé que dans les situations où l'on s'attend à ce que l'utilisateur puisse résoudre le conflit et soumettre à nouveau la requête. L'organisme d'intervention devrait inclure suffisamment d'information pour permettre à l'utilisateur de reconnaître la source du conflit. Idéalement, l'entité de réponse serait suffisamment d'informations pour l'utilisateur ou de l'agent utilisateur pour résoudre le problème; toutefois, cela pourrait ne pas être possible et n'est pas nécessaire.

les conflits sont plus susceptibles de se produire en réponse à une demande de PUT. Par exemple, si le versioning était utilisé et que l'entité mise incluait des modifications à une ressource qui entrent en conflit avec celles faites par une requête antérieure (tierce partie), le serveur pourrait utiliser la réponse 409 pour indiquer qu'il ne peut pas pour compléter la demande. Dans ce cas, l'entité de réponse contiendrait probablement une liste des différences entre les deux versions dans un format défini par le type de contenu de la réponse.

711
répondu Wrikken 2010-09-29 21:31:13

personnellement je vais avec l'extension WebDAV 422 Unprocessable Entity .

de REPOS qu'il décrit comme

le code de statut 422 Unprocessable Entity signifie que le serveur comprend le type de contenu de l'entité de requête (par conséquent, un code de statut 415 Unsupported Media Type est inapproprié), et la syntaxe de l'entité de requête est correcte (par conséquent, un code de statut 400 Bad Request est inapproprié) mais n'a pas été en mesure de traiter le contenu instruction.

64
répondu Gareth 2014-11-05 14:16:31

selon RFC 7231 , un 303 voir autre peut être utilisé si le résultat du traitement d'un POST serait équivalent à un la représentation d'une ressource existante .

51
répondu Nullius 2017-03-28 13:03:17

en retard au jeu peut-être mais je suis tombé sur ce problème sémantique tout en essayant de faire une API de repos.

pour développer un peu la réponse de Wrikken, je pense que vous pourriez utiliser soit 409 Conflict ou 403 Forbidden selon la situation - en bref, utiliser une erreur 403 quand l'utilisateur ne peut absolument rien faire pour résoudre le conflit et compléter la demande (par exemple, ils ne peuvent pas envoyer une demande DELETE pour supprimer explicitement la ressource), ou utiliser 409 si quelque chose pourrait faire éventuellement.

10.4.4 403 Interdit

Le serveur a compris la requête, mais refuse de la satisfaire. L'autorisation n'aidera pas et la demande ne doit pas être répétée. Si la méthode de requête N'était pas HEAD et le serveur souhaite rendre publique pourquoi la demande n'a pas été remplies, il DOIT décrire la raison pour le refus de l'entité. Si le serveur ne souhaite pas faire cette information à la disposition du client, le code de statut 404 (pas Trouvé) peut être utilisé à la place.

de nos jours, quelqu'un dit "403" et un problème de permissions ou d'authentification vient à l'esprit, mais la spécification dit que c'est essentiellement le serveur disant au client qu'il ne va pas le faire, ne le demandez pas à nouveau, et voici pourquoi le client ne devrait pas.

comme pour PUT vs. POST ... POST doit être utilisé pour créer un nouveau exemple d'une ressource lorsque l'utilisateur n'a pas les moyens ou ne devrait pas créer un identificateur de la ressource. PUT est utilisé lorsque l'identité de la ressource est connue.

9.6 METTRE

...

la différence fondamentale entre les requêtes POST et PUT est reflétés dans les différents sens de l'URI de Demande. L'URI dans un POST request identifie la ressource qui manipulez le entité. Cette ressource pourrait être un processus d'acceptation des données, une passerelle vers un protocole ou d'une entité distincte qui accepte les annotations. Dans par contre, L'URI d'une requête PUT identifie l'entité la requête -- l'agent utilisateur sait ce que L'URI est prévu et le le serveur ne doit pas essayer d'appliquer la requête à une autre ressource. Si le serveur souhaite que la requête soit appliquée à un URI différent,

il doit envoyer un 301 (Moved permanently) intervention, l'agent utilisateur PEUT puis prendre sa propre décision quant à savoir si oui ou non rediriger le demande.

16
répondu p0lar_bear 2015-12-24 22:40:20

et si on rendait un 418?

parce que le client demande à persister une entité qui existe déjà sur le serveur, le serveur devient finalement fou et pense qu'il est une théière et retourne: 418 I'm a teapot .

, les Références:

13
répondu рüффп 2017-07-20 20:45:31

"trouvé 302" semble logique pour moi. Et le RFC 2616 dit qu'il peut être répondu à d'autres requêtes que GET et HEAD (et cela inclut sûrement POST)

Mais il garde toujours le visiteur d'aller à cette URL pour obtenir ce "Trouvé" des ressources, par la RFC. Pour le faire passer directement à L'URL "trouvée" réelle, il faut utiliser "303 voir autre", ce qui a du sens, mais force un autre appel à obtenir son URL suivante. Du bon côté, cette Obtenir est pouvant être mis en cache.

je pense que je voudrais utiliser "303 Voir d'Autres" . Je ne sais pas si je peux répondre avec la "chose" trouvée dans le corps, mais je voudrais le faire pour sauver un aller-retour au serveur.

mise à jour: après avoir relu le RFC, je pense toujours qu'un code inexistant " 4XX+303 trouvé " devrait être le code correct. Cependant ,le "conflit 409" est le meilleur code de réponse existant. (comme indiqué par @ Wrikken), peut-être y compris un en-tête de localisation pointant vers la ressource existante.

11
répondu alanjds 2016-05-20 19:13:38

Je ne pense pas que tu devrais faire ça.

La POSTE est, comme vous le savez, à modifier la collection, et il est utilisé pour CRÉER un nouvel élément. Donc, si vous envoyez l'id (je pense que ce n'est pas une bonne idée), vous devriez modifier la collection, c.-à-d., modifier l'article, mais c'est confus.

utilisez-le pour ajouter un article, sans id. C'est la meilleure pratique.

si vous voulez capturer une contrainte UNIQUE (pas l'id) vous pouvez répondre 409, comme vous pouvez faire dans le demandes de. Mais pas l'ID.

8
répondu Alfonso Tienda 2016-11-07 11:01:42

Pourquoi pas un 202 Accepté ? C'est une requête OK (200s), il n'y avait pas d'erreurs client (400s), en soi.

À Partir De 10 Code D'État Définitions De :

" 202 Accepted. La demande a été acceptée pour traitement, mais le traitement n'est pas terminé."

... parce qu'il n'a pas besoin d'être terminée, car il existait déjà. Client il ne sait pas qu'il existe déjà, ils n'ont rien fait de mal.

je penche pour lancer un 202, et retourner un contenu similaire à ce qu'un GET /{resource}/{id} aurait retourné.

6
répondu Phillip Harrington 2016-03-17 22:12:48

je pense que pour le repos, vous avez juste à prendre une décision sur le comportement pour ce système particulier dans lequel cas, je pense que la "bonne" réponse serait l'une des deux réponses données ici. Si vous voulez que la requête s'arrête et se comporte comme si le client avait fait une erreur qu'il doit corriger avant de continuer, utilisez 409. Si le conflit n'est pas si important et que vous voulez maintenir la requête en marche, alors répondez en redirigeant le client vers l'entité qui a été trouvée. Je pense que le repos approprié APIs devrait être rediriger (ou au moins fournir l'en-tête de l'emplacement) vers le point D'extrémité GET pour cette ressource suivant un POST de toute façon, de sorte que ce comportement donnerait une expérience cohérente.

EDIT: Il est également intéressant de noter que vous devriez envisager un PUT puisque vous fournissez la carte D'identité. Le comportement est simple: "je n'aime pas ce qui est là maintenant, mettez cette chose là."C'est-à-dire que si rien n'est là, il sera créé; si quelque chose est là, il sera remplacé. I think a POST is plus approprié lorsque le serveur gère cet ID. Séparer les deux concepts vous indique essentiellement comment le gérer (c.-à-D. Mettre est idempotent donc il devrait toujours fonctionner aussi longtemps que la charge utile valide, POST crée toujours, donc s'il y a une collision D'IDs, alors un 409 décrirait ce conflit).

6
répondu Sinaesthetic 2017-09-27 19:02:04

un autre traitement possible est L'utilisation de PATCH après tout. Un PATCH est défini comme quelque chose qui change l'état interne et n'est pas limité à ajouter.

PATCH résoudrait le problème en vous permettant de mettre à jour des éléments déjà existants. Voir: RFC 5789: PATCH

4
répondu Martin Kersten 2015-09-07 11:33:37

je voudrais aller avec 422 Unprocessable Entity , qui est utilisé lorsqu'une demande n'est pas valide, mais le problème n'est pas dans la syntaxe ou d'authentification.

comme argument contre d'autres réponses, utiliser un code d'erreur non - 4xx impliquerait que ce n'est pas une erreur du client, et c'est évidemment le cas. Utiliser un code d'erreur autre que 4xx pour représenter une erreur de client n'a aucun sens.

Il semble que 409 Conflict est la réponse la plus courante ici, mais, selon le spec, qui implique que la ressource existe déjà et les nouvelles données que vous lui appliquez est incompatible avec son état actuel. Si vous envoyez une requête POST , avec, par exemple, un nom d'utilisateur qui est déjà pris, ce n'est pas en fait en conflit avec la ressource cible, car la ressource cible n'a pas encore été affichée. C'est une erreur spécifiquement pour le contrôle de version, lorsqu'il existe un conflit entre la version de la ressource stockée et de 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 requête basée sur cette version incorrecte qui ne serait plus valide conditionnellement. "Dans ce cas, la réponse contiendrait probablement des renseignements utiles pour fusionner les différences en fonction de l'historique des révisions."La demande de créer 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 le record, 422 est aussi le code de statut que GitHub utilise lorsque vous essayez de créer un dépôt par un nom déjà utilisé.

3
répondu Grant Gryczan 2018-06-30 07:24:11

Qu'en est-il 208 - http://httpstatusdogs.com/208-already-reported ? C'est qu'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 pas d'erreur non plus du côté du client ou du serveur.

2
répondu Fernando Ferreira 2015-07-31 18:07:13

est tombé sur cette question tout en vérifiant le code correct pour le double enregistrement.

pardonnez mon ignorance mais je ne comprends pas pourquoi tout le monde ignore le code "300" qui dit clairement "à choix multiples" ou "ambigu "

à mon avis, ce serait le code parfait pour construire un système non standard ou un système particulier pour votre propre usage. J'ai peut-être tort!

https://tools.ietf.org/html/rfc7231#section-6.4.1

2
répondu Hitin 2017-01-02 14:01:07

plus probable il est 400 Bad Request

6.5.1. 400 Mauvaise Demande



Le code d'état 400 (mauvaise requête) indique que le serveur ne peut pas ou ne pas traiter la demande en raison de quelque chose qui est perçu comme une erreur de client (par exemple, une syntaxe de requête mal formée, une requête non valide cadrage de message, ou demande trompeuse routage.)

comme la requête contient une valeur dupliquée(valeur qui existe déjà), elle peut être perçue comme une erreur du client. Besoin de changer la requête avant le prochain essai.

En considérant ces faits, nous pouvons conclure que le statut HTTP 400 Mauvaise demande.

1
répondu Mohammed Safeer 2018-08-06 09:03:56

il s'agit de contexte , et aussi qui est responsable d'avoir des doublons (serveur ou client ou les deux)

Si le serveur juste point de le dupliquer , regardez 4xx:

  • 400 Bad Request - lorsque le serveur ne peut pas traiter la demande car il est évident faute du client
  • 409 conflit-si le serveur ne traite pas la requête, mais la raison pour cela n'est pas la faute du client

pour implicite manipulation de doublons, regardez 2XX:

  • 200 OK
  • 201 Créé

si le serveur est prévu pour retourner quelque chose , regardez 3XX:

  • 302 Found
  • 303 Voir Autres

lorsque le serveur est capable de pointer la ressource existante, implique une redirection.

si ce n'est pas suffisant, il est toujours une bonne pratique de préparer un message d'erreur dans le corps de la réponse.

1
répondu Sławomir Lenart 2018-08-08 12:04:56