Est-ce que REST peut renvoyer du contenu après le POST?

88

J'utilise RESTlet et j'ai créé une ressource. Je gère POST en remplaçant la acceptRepresentationméthode.

Le client doit m'envoyer des données, puis je les stocke dans DB, définit la réponse sur 201 (SUCCESS_CREATED) et je dois renvoyer des données au client, mais retourne le type de acceptRepresentationest void.

Dans mon cas, je dois retourner un identifiant afin que le client puisse accéder à cette ressource.

Par exemple, si j'avais une ressource avec une URL /resourceet que le client envoie une demande POST, j'ajoute une nouvelle ligne dans DB et son adresse devrait être /resource/{id}. J'ai besoin d'envoyer {id}.

Est-ce que je fais quelque chose de mal? Les principes REST permettent-ils de retourner quelque chose après le POST? Si oui, comment puis-je le faire, et si non, quelle est la manière de gérer cette situation?

del-boy
la source
Voir la réponse de Thom pour savoir comment définir le corps de la réponse depuis acceptRepresentation ().
Avi Flax

Réponses:

96

REST dit simplement que vous devez vous conformer à l'interface uniforme. En d'autres termes, il indique que vous devez faire ce que POST est censé faire selon la spécification HTTP . Voici la citation de cette spécification qui est pertinente,

Si une ressource a été créée sur le serveur d'origine, la réponse DEVRAIT être 201 (Créée) et contenir une entité qui décrit l'état de la demande et se réfère à la nouvelle ressource, et un en-tête Location (voir la section 14.30).

Comme vous pouvez le voir, vous avez deux emplacements où vous pouvez indiquer au client où réside la ressource nouvellement créée. L'en-tête Location doit avoir une URL qui pointe vers la nouvelle ressource et vous pouvez également renvoyer une entité avec les détails.

Je ne suis pas sûr de la différence entre la substitution d'acceptRepresentation () et la substitution de post (), mais cet exemple montre comment renvoyer une réponse à partir d'un POST.

Darrel Miller
la source
2
@ del-boy: Voir la réponse de Thom pour savoir comment définir le corps de la réponse depuis acceptRepresentation ().
Avi Flax
1
La citation de spécification HTTP n'interdit pas une réponse, si vous regardez dans la section 6, il est clair à ce sujet: elle est autorisée: Request and Response messages MAY transfer an entity if not otherwise restricted by the request method or response status code. An entity consists of entity-header fields and an entity-body, although some responses will only include the entity-headers.
MikeF
@MikeF Je n'avais pas l'intention de déduire qu'un corps de réponse n'était pas autorisé. La partie de la spécification que j'ai citée dit spécifiquement "et contient une entité". J'aurais dû être plus clair dans mon texte.
Darrel Miller
16

Je renoncerais à envoyer quoi que ce soit dans le corps de la réponse. Définissez simplement Location: sur l'URL (complète) de la ressource nouvellement créée.

Votre description suggère que c'est exactement la sémantique que vous:

  1. POSTER une chose pour la créer
  2. Répondez avec suffisamment pour savoir deux choses:
    1. Que la création est arrivée (le 201)
    2. Où trouver la nouvelle chose (l'en-tête Location)

Tout le reste est superflu.

cdent
la source
Non pas que Wikipédia soit toujours une bonne source, mais cela prétend aussi "[...] Pour fournir des informations sur l'emplacement d'une ressource nouvellement créée. Dans ce cas, l'en-tête Location doit être envoyé avec un code d'état HTTP 201 ou 202 . "
Arjan
1
POST peut exécuter une logique qui crée une ou plusieurs ressources. Le résultat du traitement peut être requis par le client. Ainsi, le renvoyer dans la réponse évite de devoir effectuer un ou plusieurs appels GET à l'API. Les données créées / modifiées par la méthode POST peuvent ne pas être (et ne sont souvent pas) superflues pour le client.
Paulo Merson
10

Deux questions différentes:

Le modèle d'application REST prend-il en charge le renvoi de données dans un POST?

Je ne pense pas que REST le rejette explicitement, mais le traitement préféré est précisé dans la réponse de Darrel.

Le framework RESTlet permet-il de renvoyer des données dans un POST?

Oui, même si elle renvoie void, dans une classe qui étend Resource, vous avez un accès complet à l'objet objet Response via la méthode getResponse (). Vous pouvez donc appeler getResponse (). SetEntity () avec les données de votre choix.

Thom
la source
6

Sortez-le dans le format demandé. Cela pourrait être:

<success>
    <id>5483</id>
</success>

Ou:

{ "type": "success", "id": 5483 }

Cela dépend de ce que vous faites habituellement. S'ils n'attendent pas les données, ils devraient simplement les ignorer, mais tout client qui souhaite les gérer correctement devrait pouvoir le faire.

Samir Talwar
la source
Ok, j'ai deux formats possibles (html et xml). Je sais comment gérer le type de format demandé, mais je ne sais pas comment ajouter des données à la réponse. La méthode represent renvoie la représentation, donc je retourne simplement ce que je veux, mais acceptRepresentation est une méthode void, donc je ne peux pas retourner de données ...
del-boy
1

Si vous répondez 201 Created avec un corps d'entité, plutôt qu'une redirection d'emplacement, il est judicieux d'inclure un en-tête Content-Location pointant vers la ressource qui est représentée dans la réponse.

Cela évitera une confusion potentielle - dans laquelle un client pourrait (à juste titre) supposer que l'entité de réponse représente en fait un nouvel état du «créateur», et non la ressource créée.

> POST /collection
> ..new item..

< 201 Created
< Location: /collection/1354
< Content-Location: /collection/1354
< <div class="item">This is the new item that was created</div>
Mike
la source
3
Je pense que Content-Location a un but différent. La spécification HTTP indique que Content-Location n'est pas défini pour POST et PUT. L'en-tête Location est utilisé avec un 201-Create. Le retour d'un emplacement ne fait pas automatiquement une redirection, vous avez besoin d'un code de réponse 3XX pour cela.
Darrel Miller
1
L'en-tête d'emplacement est utilisé (dans une réponse 201) pour indiquer où se trouve la ressource créée; il n'est pas pertinent pour le corps de l'entité de la réponse qu'il accompagne. Mon point était que - si vous vouliez inclure la ressource créée dans la réponse 201 elle-même (plutôt que de diriger / rediriger le client vers un autre URI), un en-tête d'emplacement de contenu serait une bonne idée. C'est probablement un peu «plier les règles», mais c'est plus efficace que d'exiger un autre cycle de demande / réponse pour obtenir l'état de la nouvelle ressource au client.
Mike
Ça a du sens pour moi. Je n'ai jamais utilisé l'en-tête Content-Location auparavant.
Darrel Miller
si le client est un humain avec un navigateur, renvoyer 201 avec l'en-tête Location n'a aucun sens. L'utilisateur ne saura pas quoi en faire. si le client est un robot, il peut être programmé pour savoir comment le gérer - comme un suivi GET sur l'emplacement.
irréprochable
3
@irreputable: Je crois que REST était destiné à la conception d'API, où A ne représente pas un agent utilisateur qui recherche du HTML à rendre.
Hermes