Question PUT vs. POST dans REST


Selon les spécifications HTTP / 1.1:

le POST méthode est utilisée pour demander que le serveur d'origine accepte l'entité incluse dans la requête en tant que nouveau subordonné de la ressource identifiée par le Request-URI dans le Request-Line

En d'autres termes, POST est utilisé pour créer.

le PUT La méthode demande que l'entité incluse soit stockée sous le Request-URI. Si la Request-URI fait référence à une ressource déjà existante, l'entité incluse DEVRAIT être considérée comme une version modifiée de celle résidant sur le serveur d'origine. Si la Request-URI ne pointe pas vers une ressource existante, et que l'URI est capable d'être défini comme une nouvelle ressource par l'agent utilisateur demandeur, le serveur d'origine peut créer la ressource avec cet URI. "

C'est, PUT est utilisé pour créer ou mettre à jour.

Alors, lequel devrait être utilisé pour créer une ressource? Ou faut-il soutenir les deux?


4456
2018-03-10 14:25


origine


Réponses:


Global: 

Les deux PUT et POST peuvent être utilisés pour créer.

Vous devez demander "à quoi faites-vous l'action?" pour distinguer ce que vous devriez utiliser. Supposons que vous concevez une API pour poser des questions. Si vous voulez utiliser POST alors vous feriez cela à une liste de questions. Si vous voulez utiliser PUT alors vous feriez cela à une question particulière.

Les deux peuvent être utilisés, alors lequel dois-je utiliser dans mon design RESTful:

Vous n'avez pas besoin de prendre en charge à la fois PUT et POST.

Lequel est utilisé est laissé à vous. Mais n'oubliez pas d'utiliser le bon en fonction de l'objet auquel vous faites référence dans la demande.

Quelques considérations:

  • Est-ce que vous nommez vos objets URL que vous créez explicitement, ou laissez le serveur décider? Si vous les nommez, utilisez PUT. Si vous laissez le serveur décider, utilisez POST.
  • PUT est idempotent, donc si vous mettez deux fois un objet, cela n'a aucun effet. C'est une belle propriété, donc j'utiliserais PUT si possible.
  • Vous pouvez mettre à jour ou créer une ressource avec PUT avec la même URL d'objet
  • Avec POST vous pouvez avoir 2 demandes en même temps en apportant des modifications à une URL, et ils peuvent mettre à jour différentes parties de l'objet.

Un exemple:

J'ai écrit ce qui suit dans le cadre d'une autre réponse sur SO en ce qui concerne:

POSTER:

Utilisé pour modifier et mettre à jour une ressource

POST /questions/<existing_question> HTTP/1.1
Host: www.example.com/

Notez que ce qui suit est une erreur:

POST /questions/<new_question> HTTP/1.1
Host: www.example.com/

Si l'URL n'est pas encore créée, vous   ne devrait pas utiliser POST pour le créer   en spécifiant le nom. Ceci devrait   résulter en une erreur 'ressource non trouvée'   car <new_question> n'existe pas   encore. Vous devriez mettre le <new_question>   ressource sur le serveur en premier.

Vous pourriez cependant faire quelque chose comme   ceci pour créer des ressources en utilisant POST:

POST /questions HTTP/1.1
Host: www.example.com/

Notez que dans ce cas la ressource   nom n'est pas spécifié, les nouveaux objets   Le chemin de l'URL vous sera renvoyé.

METTRE: 

Utilisé pour créer une ressource, ou   réécrit dessus. Pendant que vous spécifiez le   ressources nouvelle URL.

Pour une nouvelle ressource:

PUT /questions/<new_question> HTTP/1.1
Host: www.example.com/

Pour remplacer une ressource existante:

PUT /questions/<existing_question> HTTP/1.1
Host: www.example.com/

3480
2018-03-10 14:29



Vous pouvez trouver des affirmations sur le web qui disent

Ni l'un ni l'autre n'a raison.


Mieux vaut choisir entre PUT et POST en fonction de idempotence de l'action.

METTRE implique de mettre une ressource - en remplaçant complètement ce qui est disponible à l'URL donnée par une chose différente. Par définition, un PUT est idempotent. Faites-le autant de fois que vous le souhaitez, et le résultat est le même. x=5 est idempotent. Vous pouvez METTRE une ressource si elle existe déjà, ou pas (par exemple, pour créer, ou mettre à jour)!

POSTER met à jour une ressource, ajoute une ressource subsidiaire ou provoque une modification. Un POST n'est pas idempotent, de la manière x++ n'est pas idempotent.


Par cet argument, PUT est à créer lorsque vous connaissez l'URL de la chose que vous allez créer. POST peut être utilisé pour créer quand vous connaissez l'URL de la "usine" ou du gestionnaire pour la catégorie de choses que vous voulez créer.

alors:

POST /expense-report

ou:

PUT  /expense-report/10929

1878
2018-04-22 14:55



  • POSTER à une URL crée une ressource enfant à serveur défini URL
  • METTRE à une URL crée / remplace la ressource dans son intégralité à la client défini URL
  • PIÈCE à une URL mises à jour partie de la ressource à cette URL définie par le client.

La spécification pertinente pour PUT et POST est RFC 2616 §9.5ff.

POST crée une ressource enfant, donc POST à /items crée une ressource qui vit sous le /items Ressource. Par exemple. /items/1. Envoyer deux fois le même paquet de messages créera deux ressources.

METTRE est pour créer ou remplacer une ressource à un URL connue du client.

Donc: METTRE est uniquement un candidat pour CREATE où le client connaît déjà l'URL avant la création de la ressource. Par exemple. /blogs/nigel/entry/when_to_use_post_vs_put comme le titre est utilisé comme clé de ressource

METTRE remplace la ressource à l'URL connue si elle existe déjà, donc envoyer deux fois la même requête n'a aucun effet. En d'autres termes, les appels à PUT sont idempotents.

Le RFC se lit comme ceci:

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

Remarque: PUT a surtout été utilisé pour mettre à jour des ressources (en les remplaçant dans leur intégralité), mais récemment il y a un mouvement vers l'utilisation de PATCH pour mettre à jour les ressources existantes, comme PUT spécifie qu'il remplace la ressource entière. RFC 5789.


562
2018-04-07 05:52



Résumé:

Créer:

Peut être effectué avec PUT ou POST de la façon suivante:

METTRE

Crée LA nouvelle ressource avec newResourceId comme identifiant, sous l'URI / resources, ou collection.

PUT /resources/<newResourceId> HTTP/1.1 

POSTER

Crée UNE nouvelle ressource sous l'URI / resources, ou collection. Habituellement, l'identifiant est renvoyé par le serveur.

POST /resources HTTP/1.1

Mettre à jour:

Pouvez seulement être effectué avec PUT de la façon suivante:

METTRE

Met à jour la ressource avec existingResourceId comme identifiant, sous l'URI / resources, ou collection.

PUT /resources/<existingResourceId> HTTP/1.1

Explication:

Lorsque vous traitez avec REST et URI comme général, vous avez générique sur le la gauche et spécifique sur le droite. le génériques sont généralement appelés des collections et plus spécifique les articles peuvent être appelés Ressource. Notez qu'un Ressource peut contenir un collection.

Exemples:

<- générique - spécifique ->

URI: website.com/users/john
website.com  - whole site
users        - collection of users
john         - item of the collection, or a resource

URI:website.com/users/john/posts/23
website.com  - whole site
users        - collection of users
john         - item of the collection, or a resource
posts        - collection of posts from john
23           - post from john with identifier 23, also a resource

Lorsque vous utilisez POST, vous êtes toujours se référant à un collectiondonc quand vous dites:

POST /users HTTP/1.1

vous publiez un nouvel utilisateur sur utilisateurs  collection.

Si vous continuez et essayez quelque chose comme ceci:

POST /users/john HTTP/1.1

ça va marcher, mais sémantiquement vous dites que vous voulez ajouter une ressource à la John  collection sous le utilisateurs  collection.

Une fois que vous utilisez PUT vous faites référence à un Ressource ou un seul article, éventuellement à l'intérieur d'un collection. Alors quand vous dites:

PUT /users/john HTTP/1.1

vous dites à la mise à jour du serveur, ou créer si elle n'existe pas, le John  Ressource sous le utilisateurs  collection.

Spec:

Permettez-moi de souligner certaines parties importantes de la spécification:

POSTER

le POSTER méthode est utilisée pour demander que le serveur d'origine Acceptez l'entité incluse dans la demande en tant que Nouveau subalterne de la ressource identifiée par l'URI de demande dans la ligne de requête

Par conséquent, crée un nouveau Ressource sur un collection.

METTRE

le METTRE méthode demande que l'entité incluse soit stocké sous l'URI de demande fourni. Si l'URI de demande fait référence à un déjà existante ressource, l'entité ci-jointe DEVRAIT être considérée comme version modifiée de celui résidant sur le serveur d'origine. Si l'URI de demande pas pointer vers un existant ressource, et cette URI est capable d'être défini comme Nouveau Ressource par l'agent utilisateur demandeur, le serveur d'origine peut créer la ressource avec cet URI. "

Par conséquent, créer ou mettre à jour en fonction de l'existence de la Ressource.

Référence:


165
2017-08-14 22:47



Je voudrais ajouter mon conseil "pragmatique". Utilisez PUT lorsque vous connaissez le "id" par lequel l'objet que vous enregistrez peut être récupéré. L'utilisation de PUT ne fonctionnera pas très bien si vous avez besoin, par exemple, d'un identifiant généré par une base de données pour que vous puissiez effectuer des recherches ou des mises à jour ultérieures.

Donc: Pour enregistrer un utilisateur existant, ou un où le client génère l'ID et il a été vérifié que l'ID est unique:

PUT /user/12345 HTTP/1.1  <-- create the user providing the id 12345
Host: mydomain.com

GET /user/12345 HTTP/1.1  <-- return that user
Host: mydomain.com

Sinon, utilisez POST pour créer initialement l'objet et PUT pour mettre à jour l'objet:

POST /user HTTP/1.1   <--- create the user, server returns 12345
Host: mydomain.com

PUT /user/12345 HTTP/1.1  <--- update the user
Host: mydomain.com

156
2018-01-15 19:59



POST signifie "créer nouveau" comme dans "Voici l'entrée pour créer un utilisateur, créez-le pour moi".

PUT signifie "insérer, remplacer s'il existe déjà" comme dans "Voici les données pour l'utilisateur 5".

Vous POST à ​​example.com/users puisque vous ne connaissez pas encore l'URL de l'utilisateur, vous voulez que le serveur le crée.

Vous METTEZ sur example.com/users/id puisque vous voulez remplacer / créer un spécifique utilisateur.

POSTing deux fois avec les mêmes données signifie créer deux utilisateurs identiques avec des ID différents. PUTing deux fois avec les mêmes données crée l'utilisateur le premier et le met à jour au même état la deuxième fois (pas de changements). Puisque vous vous retrouvez avec le même état après un PUT, peu importe combien de fois vous l'exécutez, il est dit être «tout aussi puissant» à chaque fois - idempotent. Ceci est utile pour réessayer automatiquement les demandes. Vous n'avez plus besoin de «renvoyer» lorsque vous appuyez sur le bouton Précédent du navigateur.

Un conseil général est d'utiliser POST lorsque vous avez besoin que le serveur contrôle la génération d'URL de vos ressources. Utilisez PUT sinon. Préférez PUT sur POST.


145
2017-10-23 14:27



Utilisez POST pour créer et PUT pour mettre à jour. C'est comme ça que Ruby on Rails le fait, de toute façon.

PUT    /items/1      #=> update
POST   /items        #=> create

105
2018-03-10 14:28



REST est un très concept de haut niveau. En fait, il ne mentionne même pas du tout le protocole HTTP!

Si vous avez des doutes sur la façon d'implémenter REST dans HTTP, vous pouvez toujours jeter un coup d'œil à Protocole de publication Atom (AtomPub) spécification. AtomPub est un standard pour l'écriture de services Web RESTful avec HTTP qui a été développé par de nombreux luminaires HTTP et REST, avec une contribution de Roy Fielding, l'inventeur de REST et (co-) inventeur de HTTP lui-même.

En fait, vous pourriez même utiliser AtomPub directement. Bien qu'il soit issu de la communauté des blogs, il n'est en aucun cas limité au blogging: c'est un protocole générique pour interagir RESTfully avec des collections arbitraires (imbriquées) de ressources arbitraires via HTTP. Si vous pouvez représenter votre application comme une collection imbriquée de ressources, vous pouvez simplement utiliser AtomPub et ne pas vous soucier d'utiliser PUT ou POST, les codes d'état HTTP à renvoyer et tous ces détails.

C'est ce qu'AtomPub a à dire sur la création de ressources (section 9.2):

Pour ajouter des membres à une collection, les clients envoient des requêtes POST à ​​l'URI de la collection.


58
2018-03-10 15:27