Créer une demande avec POST, quels codes de réponse 200 ou 201 et le contenu

Supposons que j'écris un service REST dont l'intention est d'ajouter un nouvel élément de données à un système.

Je prévois de poster à

http://myhost/serviceX/someResources

Supposons que cela fonctionne, quel code de réponse dois-je utiliser? Et quel contenu pourrais-je retourner?

Je regarde les définitions des codes de réponse HTTP et vois ces possibilités:

200: retourne une entité décrivant ou contenant le résultat de l'action;

201: ce qui signifie créé. Signification * la demande a été rempli et a donné lieu à une nouvelle ressource en cours de création. La ressource nouvellement créée peut être référencée par les URI (s) retournés dans l'entité de la réponse, avec L'URI le plus spécifique pour la ressource donnée par un champ D'en-tête D'emplacement. La réponse doit inclure une entité contenant une liste des caractéristiques des ressources et des emplacements à partir desquels l'utilisateur ou l'agent utilisateur peut choisir celui qui convient le mieux. Le format d'entité est spécifié par le type de support indiqué dans le champ D'en-tête Content-Type. *

Ce dernier semble plus conforme à la spécification Http, mais je ne suis pas du tout clair quoi

La réponse doit inclure une entité contenant une liste de ressources caractéristiques et emplacement(s)

Signifie.

Recommandations? Les interprétations?

77
demandé sur Mark Stewart 2009-12-07 18:20:06

7 réponses

Http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.19

C'est juste une valeur-clé délimitée par deux-points.

ETag: "xyzzy"

Il peut s'agir de n'importe quel type de données texte - j'inclue généralement une chaîne JSON avec l'identifiant de l'élément créé. La facilité de tester seul fait y compris vaut la peine.

ETag: "{ id: 1234, uri: 'http://domain.com/comments/1234', type: 'comment' }"

Dans cet exemple, l'identifiant, l'uri et le type de l'élément créé sont les "caractéristiques et l'emplacement de la ressource".

9
répondu tempire 2009-12-27 05:46:41

Je pense que ATOMPUB REST API est un excellent exemple de service restful. Voir l'extrait ci-dessous de la spécification atompub:

POST /edit/ HTTP/1.1
Host: example.org
User-Agent: Thingio/1.0
Authorization: Basic ZGFmZnk6c2VjZXJldA==
Content-Type: application/atom+xml;type=entry
Content-Length: nnn
Slug: First Post

<?xml version="1.0"?>
<entry xmlns="http://www.w3.org/2005/Atom">
  <title>Atom-Powered Robots Run Amok</title>
  <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
  <updated>2003-12-13T18:30:02Z</updated>
  <author><name>John Doe</name></author>
  <content>Some text.</content>
</entry>

Le serveur signale une création réussie avec un code d'état de 201. La réponse comprend un en-tête D'emplacement indiquant L'URI D'entrée de membre de l'entrée D'atome, et une représentation de cette entrée dans le corps de la réponse.

HTTP/1.1 201 Created
Date: Fri, 7 Oct 2005 17:17:11 GMT
Content-Length: nnn
Content-Type: application/atom+xml;type=entry;charset="utf-8"
Location: http://example.org/edit/first-post.atom
ETag: "c180de84f991g8"  

<?xml version="1.0"?>
<entry xmlns="http://www.w3.org/2005/Atom">
  <title>Atom-Powered Robots Run Amok</title>
  <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
  <updated>2003-12-13T18:30:02Z</updated>
  <author><name>John Doe</name></author>
  <content>Some text.</content>
  <link rel="edit"
      href="http://example.org/edit/first-post.atom"/>
</entry>

L'entrée créée et renvoyée par la Collection peut ne pas correspondre à l'entrée publiée par le client. Un serveur peut modifiez les valeurs de divers éléments de l'entrée, tels que les valeurs atom: id, atom: updated et atom: author, et vous pouvez choisir de supprimer ou d'ajouter d'autres éléments et attributs, ou de modifier le contenu des éléments et les valeurs des attributs.

77
répondu Chandra Patni 2009-12-27 05:58:44

L'idée est que le corps de réponse vous donne une page qui vous lie à la chose:

201 Créé

Le code D'état 201 (créé) indique que la demande a été remplie et qu'une ou plusieurs nouvelles ressources ont été créées. La ressource principale créée par la demande est identifiée soit par un champ D'en-tête D'emplacement dans la réponse, soit, si aucun champ D'emplacement n'est reçu, par L'URI de demande effective.

Cela signifie que vous comprendrait un Location dans la réponse header, ce qui donne l'URL de l'endroit où vous pouvez trouver de la nouvellement créée chose:

HTTP/1.1 201 Created
Date: Sat, 02 Apr 2016 12:22:40 GMT
Location: http://stackoverflow.com/a/36373586/12597

Corps de réponse

Ils vont ensuite mentionner ce que vous devez inclure dans la réponse body :

La charge utile de réponse 201 décrit généralement les ressources créées et les lie à celles-ci.

Pour l'humain en utilisant le navigateur, vous leur donnez quelque chose qu'ils peuvent regarder, et cliquez, pour arriver à leur ressource nouvellement créée:

HTTP/1.1 201 Created
Date: Sat, 02 Apr 2016 12:22:40 GMT
Location: http://stackoverflow.com/a/36373586/12597
Content-Type: text/html

Your answer has been saved! 
Click <A href="/a/36373586/12597">here</A> to view it.

Si la page ne sera utilisée que par un robot, il est logique que la réponse soit lisible par ordinateur:

HTTP/1.1 201 Created
Date: Sat, 02 Apr 2016 12:22:40 GMT
Location: http://stackoverflow.com/a/36373586/12597
Content-Type: application/xml

<createdResources>
   <questionID>1860645</questionID>
   <answerID>36373586</answerID>
   <primary>/a/36373586/12597</primary>
   <additional>
      <resource>http://stackoverflow.com/questions/1860645/create-request-with-post-which-response-codes-200-or-201-and-content/36373586#36373586</resource>
      <resource>http://stackoverflow.com/a/1962757/12597</resource>
   </additional>
</createdResource>

Ou, si vous préférez:

HTTP/1.1 201 Created
Date: Sat, 02 Apr 2016 12:22:40 GMT
Location: http://stackoverflow.com/a/36373586/12597
Content-Type: application/json

{ 
   "questionID": 1860645, 
   "answerID": 36373586,
   "primary": "/a/36373586/12597",
   "additional": [
      "http://stackoverflow.com/questions/1860645/create-request-with-post-which-response-codes-200-or-201-and-content/36373586#36373586",
      "http://stackoverflow.com/a/36373586/12597"
   ]
}

La réponse est entièrement à vous; c'est arbitrairement ce que vous aimeriez.

Cache amical

Enfin, il y a l'optimisation que je peux pré-mettre en cache la ressource créée (parce que j'ai déjà le contenu; je viens de le télécharger). Le serveur peut renvoyer une date ou ETag que je peux stocker avec le contenu que je viens de télécharger:

Voir Section 7.2 pour une discussion sur la signification et le but des champs d'en-tête du validateur, tels que ETag et Last-Modified, dans une réponse 201.

HTTP/1.1 201 Created
Date: Sat, 02 Apr 2016 12:22:40 GMT
Location: http://stackoverflow.com/a/23704283/12597
Content-Type: text/html
ETag: JF2CA53BOMQGU5LTOQQGC3RAMV4GC3LQNRSS4
Last-Modified: Sat, 02 Apr 2016 12:22:39 GMT 

Your answer has been saved! 
Click <A href="/a/36373586/12597">here</A> to view it.

Et ETag s sont purement des valeurs arbitraires. Les avoir différents quand une ressource change (et les caches doivent être mis à jour) est tout ce qui compte. L'ETag est généralement un hachage (par exemple SHA2). Mais il peut s'agir d'une base de données rowversion, ou d'une révision incrémentée nombre. Tout ce qui va changer lorsque la chose change.

38
répondu Ian Boyd 2016-04-02 13:15:30

Consultez HTTP: définitions de méthode: POST .

L'action effectuée par la méthode POST peut ne pas aboutir à une ressource qui peut être identifiée par un URI. Dans ce cas, 200 (OK) ou 204 (pas de contenu) est l'état de réponse approprié, selon que la réponse inclut ou non une entité qui décrit le résultat.

Si une ressource a été créée sur le serveur d'origine, la réponse doit être 201 (Created) et contenir une entité qui décrit l'état de la demande et fait référence à la nouvelle ressource, et un en-tête D'emplacement (voir la section 14.30).

23
répondu ma11hew28 2014-05-16 20:45:52

En quelques mots:

  • 200 lorsqu'un objet est créé et retourné
  • 201 lorsqu'un objet est créé mais que seule sa référence est renvoyée (comme un ID ou un lien)
14
répondu Stéphane Bruckert 2017-06-06 17:13:41

La sortie dépend en fait du type de contenu demandé. Cependant, au minimum, vous devez mettre la ressource qui a été créée dans Location. Tout comme le modèle Post-Redirect-Get.

Dans mon cas, je le laisse vide jusqu'à ce qu'il soit demandé autrement. Puisque c'est le comportement de JAX-RS lors de l'utilisation de Response.créé().

Cependant, notez simplement que les navigateurs et les frameworks comme Angular ne suivent pas automatiquement 201. J'ai noté le comportement dans http://www.trajano.net/2013/05/201-created-with-angular-resource/

1
répondu Archimedes Trajano 2013-05-03 07:20:58

Une autre réponse que j'aurais pour cela serait d'adopter une approche pragmatique et de garder votre contrat D'API REST simple. Dans mon cas, j'avais refactorisé mon API REST pour rendre les choses plus testables sans recourir à JavaScript ou XHR, juste de simples formulaires et liens HTML.

Donc, pour être plus précis sur votre question ci-dessus, je voudrais simplement utiliser le code de retour 200 et que le message retourné contienne un message JSON que votre application peut comprendre. Selon vos besoins, il peut exiger L'ID de l'objet qui est nouvellement créé afin que l'application web puisse obtenir les données dans un autre appel.

Une note, dans mon contrat d'API refactorisé, les réponses POST ne doivent pas contenir de données cachables car les messages ne sont pas vraiment cachables, donc limitez-les aux identifiants qui peuvent être demandés et mis en cache à l'aide D'une requête GET.

-2
répondu Archimedes Trajano 2014-07-23 14:49:53