web-dev-qa-db-fra.com

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

Supposons que j'écrive un service REST) destiné à ajouter un nouvel élément de données à un système.

Je prévois de POST à

http://myhost/serviceX/someResources

Supposons que cela fonctionne, quel code de réponse devrais-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 CREATED. Signification * La demande a été remplie et une nouvelle ressource a été créée. La ressource nouvellement créée peut être référencée par le ou les URI retournés dans l'entité de la réponse, avec l'URI le plus spécifique pour la ressource donné par un champ d'en-tête Location. La réponse DEVRAIT inclure une entité contenant une liste de caractéristiques de ressources et un ou plusieurs emplacements parmi lesquels l'utilisateur ou l'agent d'utilisateur peut choisir celle qui convient le mieux. Le format de l'entité est spécifié par le type de média 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 ce que

La réponse DEVRAIT inclure une entité contenant une liste de caractéristiques de ressources et d’emplacement (s).

veux dire.

Des recommandations? Des interprétations?

102
djna

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'inclus généralement une chaîne JSON avec l'identifiant de l'élément créé. La facilité de test à elle seule rend l’inclusion utile.

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".

13
tempire

Je pense que atompub REST API est un excellent exemple de service reposant. 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 Location indiquant l'URI de l'entrée du membre de l'entrée Atom), ainsi qu'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 POSTée par le client. Un serveur PEUT changer les valeurs de divers éléments dans l'entrée, tels que les valeurs atom: id, atom: updated et atom: author, et PEUT choisir de supprimer ou d'ajouter d'autres éléments et attributs, ou modifier le contenu des éléments et les valeurs d'attributs.

85
Chandra Patni

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

201 créé

Le code d'état 201 (Créé) indique que la demande a été remplie et a entraîné la création d'une ou plusieurs nouvelles ressources. La ressource principale créée par la demande est identifiée par un champ d'en-tête Location dans la réponse ou, si aucun champ Location n'est reçu, par l'URI de la demande effective.

Cela signifie que vous devez inclure un Location dans la réponse en-tête qui donne l'URL de l'endroit où vous pouvez trouver le 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 mentionnent ensuite ce que vous devez inclure dans la réponse body:

La charge utile de 201 réponses décrit généralement des ressources et des liens vers les ressources créées.

Pour l'utilisateur utilisant le navigateur, vous lui donnez quelque chose qu'il peut consulter et cliquer pour accéder à sa nouvelle ressource:

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 n'est utilisée que par un robot, il est judicieux 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 voudriez.

Cache amical

Enfin, il y a l'optimisation que je peux pré-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 une heure 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 des valeurs purement arbitraires. Ce qui compte, c'est qu'ils soient différents quand une ressource change (et que les caches doivent être mis à jour). ETag est généralement un hachage (par exemple, SHA2). Mais il peut s'agir d'une base de données rowversion ou d'un numéro de révision incrémenté. Tout ce qui va changer lorsque le chose change.

61
Ian Boyd

En quelques mots:

  • 2 lorsqu'un objet est créé et est renvoyé
  • 201 lorsqu'un objet est créé mais que seule sa référence est renvoyée (comme un identifiant ou un lien)
30

Extraire HTTP: Définitions de méthodes: POST .

L'action effectuée par la méthode POST peut ne pas aboutir à une ressource pouvant être identifiée par un URI. Dans ce cas, 200 (OK) ou 204 (aucun contenu) correspond au statut 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 DEVRAIT être 201 (Créé) et contenir une entité qui décrit l'état de la demande et fait référence à la nouvelle ressource, ainsi qu'un en-tête Location (voir la section 14.30).

28
ma11hew28

La sortie dépend en réalité du type de contenu demandé. Cependant, vous devez au moins placer la ressource créée dans Emplacement. Tout comme le modèle Post-Redirect-Get.

Dans mon cas, je le laisse en blanc jusqu'à demande contraire. C'est le comportement de JAX-RS lors de l'utilisation de Response.created ().

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

1