Question Code de réponse HTTP pour 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 côté client, avec des ID d'objets 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 à l'aide de PUT:

PUT /objects/{id} HTTP/1.1
...

{json representation of the object}

Le {id} est l'ID de l'objet, donc il fait partie de l'URI de la demande.

Maintenant, je considère aussi permettre aux clients de créer l'objet en utilisant POST:

POST /objects/ HTTP/1.1
...

{json representation of the object, including ID}

Étant donné que POST est conçu comme une opération "append", je ne suis pas sûr de savoir quoi faire si l'objet est déjà présent. Dois-je traiter la demande comme une demande de modification ou devrais-je retourner un code d'erreur (lequel)?


554
2017-09-29 21:26


origine


Réponses:


Mon sentiment est 409 Conflict est le plus approprié, cependant, rarement vu dans la nature bien sûr:

La requête n'a pas pu aboutir en raison d'un conflit avec l'état actuel de la ressource. Ce code n'est autorisé que dans les situations où il est prévu que l'utilisateur puisse résoudre le conflit et renvoyer la demande. Le corps de la réponse DEVRAIT 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 n'est pas nécessaire.

Les conflits sont les plus susceptibles de se produire en réponse à une demande PUT. Par exemple, si le contrôle de version était utilisé et que l'entité PUT incluait des modifications dans une ressource en conflit avec celles effectuées par une requête antérieure (tierce partie), le serveur pouvait utiliser la réponse 409 pour indiquer qu'il ne pouvait pas terminer la requête . Dans ce cas, l'entité de réponse contiendra probablement une liste des différences entre les deux versions dans un format défini par la réponse Content-Type.


677
2017-09-29 21:31



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

REST Patterns le décrit comme

le 422 Unprocessable Entity code d'état signifie que le serveur comprend le type de contenu de l'entité de requête (d'où 415 Unsupported Media Type code d'état est inapproprié), et la syntaxe de l'entité de requête est correcte 400 Bad Request le code d'état est inapproprié) mais n'a pas pu traiter les instructions contenues.


57
2017-09-29 21:44



Selon RFC 7231, une 303 Voir autre Peut être utilisé Si le résultat du traitement d'un POST équivaut à un    représentation d'une ressource existante.


50
2017-11-09 09:54



Qu'en est-il de retourner 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:


15
2017-07-20 20:39



Tard dans le jeu peut-être mais je suis tombé sur ce problème de sémantique en essayant de faire une API REST.

Pour développer un peu la réponse de Wrikken, je pense que vous pourriez utiliser soit 409 Conflict ou 403 Forbidden en fonction de la situation - en bref, utilisez une erreur 403 lorsque l'utilisateur ne peut absolument rien faire pour résoudre le conflit et terminer la requête (par exemple, ils ne peuvent pas envoyer un DELETEdemande de supprimer explicitement la ressource), ou utilisez 409 si quelque chose pourrait éventuellement être fait.

10.4.4 403 Interdit

Le serveur a compris la requête, mais refuse de l'exécuter.   L'autorisation n'aidera pas et la demande NE DEVRAIT PAS être répétée. Si   la méthode de requête n'était pas HEAD et le serveur souhaite rendre public   pourquoi la demande n'a pas été satisfaite, elle DEVRAIT décrire la raison   pour le refus dans l'entité. Si le serveur ne souhaite pas faire   cette information disponible pour le client, le code d'état 404 (Non   Trouvé) peut être utilisé à la place.

De nos jours, quelqu'un dit "403" et un problème d'autorisation 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 demande plus, et voici pourquoi le client devrait 't.

Pour ce qui est de PUT contre. POST... POST doit être utilisé pour créer une nouvelle instance d'une ressource lorsque l'utilisateur n'a aucun moyen ou ne doit pas créer un identifiant pour la ressource. PUT est utilisé lorsque l'identité de la ressource est connue.

9.6 PUT

...

La différence fondamentale entre les requêtes POST et PUT est   reflété dans la signification différente de l'URI de demande. L'URI dans un   La requête POST identifie la ressource qui gérera le   entité. Cette ressource peut être un processus d'acceptation de données, une passerelle vers   un autre protocole ou une entité distincte qui accepte les annotations. Dans   En revanche, l'URI d'une requête PUT identifie l'entité incluse avec   la demande - l'agent utilisateur sait ce que l'URI est destiné et le   le serveur NE DOIT PAS tenter d'appliquer la demande à une autre ressource.   Si le serveur souhaite que la demande soit appliquée à un URI différent,

il DOIT envoyer une réponse 301 (Moved Permanently); l'agent utilisateur PEUT   puis prendre sa propre décision concernant la redirection ou non   demande.


14
2017-12-24 22:40



"302 Found" semble logique pour moi. 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 au visiteur d'accéder à cette URL pour obtenir cette ressource "Trouvé", par le RFC. Pour le faire aller directement à l'URL "Found", il faut utiliser "303 See Other", ce qui est logique, mais force un autre appel à GET l'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.

METTRE À JOUR: Après avoir relu le RFC, je pense toujours qu'un inexistant Le code "4XX + 303 trouvé" devrait être le bon. Cependant, le "409 Conflict" est le meilleur code de réponse existant (comme indiqué par @ Wrikken), en incluant peut-être un en-tête Location pointant vers la ressource existante.


12
2018-05-16 09:25



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'ID (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 voulez capturer une contrainte UNIQUE (pas l'identifiant), vous pouvez utiliser la réponse 409, comme vous pouvez le faire dans les requêtes PUT. Mais pas l'ID.


9
2017-09-30 10:12



Je pense que pour REST, vous devez juste 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 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 important et que vous voulez conserver la requête, 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 de localisation) au point de terminaison GET pour cette ressource après un POST de toute façon, ce comportement donnerait une expérience cohérente.

MODIFIER: Il est également important 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à". Signification, si rien n'est là, ça va être 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 dit essentiellement comment le gérer (ie PUT est idempotent donc ça devrait toujours fonctionner tant que la charge utile valide, POST crée toujours, donc s'il y a une collision d'ID, alors un 409 décrirait ce conflit) .


6
2017-10-27 04:51