«Meilleure» pratique pour une réponse POST reposante

217

Donc, rien de nouveau ici, j'essaie simplement d'obtenir des éclaircissements et je n'arrive pas à en trouver dans d'autres articles.

Je crée une nouvelle ressource avec réticence, dites:

/books (POST)

avec un corps:

{
  title: 'The Lion, the Witch and the Wardrobe',
  author: 'C. S. Lewis'
}

Je sais que je devrais retourner un 201 (créé) avec un en-tête Location de la nouvelle ressource:

Location: /books/12345

La question à laquelle je n'arrive pas à répondre par moi-même est de savoir ce que le serveur devrait retourner dans le corps.

J'ai souvent fait ce type de réponse:

{
  id: 12345,
  title: 'The Lion, the Witch and the Wardrobe',
  author: 'C. S. Lewis'
}

Je l'ai fait pour deux raisons:

  1. J'ai écrit des API pour les frameworks frontaux comme angularjs. Dans mon cas particulier, j'utilise des ressources angulaires et j'ai souvent juste besoin de l'ID de la ressource pour la localiser. Si je n'ai pas renvoyé l'ID dans le corps de la réponse, je devrais l'analyser hors de l'en-tête Location.
  2. Dans un GET de tous les livres, je retourne généralement l'objet entier, pas seulement l'id. En ce sens, mon code client n'a pas à différencier d'où obtenir l'identifiant (en-tête ou corps de l'emplacement).

Maintenant, je sais que je suis vraiment dans la zone grise ici, mais la plupart des gens disent que le retour de la ressource entière est une «mauvaise» pratique. Mais que faire si le serveur modifie / ajoute des informations à la ressource. Il ajoute définitivement l'identifiant, mais pourrait également ajouter d'autres choses comme un horodatage. Dans le cas où je ne renvoie pas la totalité de la ressource, est-il vraiment préférable de faire un POST, de renvoyer l'ID, puis de demander au client d'effectuer un GET pour obtenir la nouvelle ressource.

perdu dans la traduction
la source
Personnellement, je préfère un corps vide pour les réponses POST. La valeur d'en-tête RESTful Location ne doit-elle pas être un URI (identifiant de ressource unique)? Alors peut-être devriez-vous l'utiliser comme ID et ne pas l'analyser pour trouver un ID interne du serveur. Les consommateurs de l'OMI et de l'API RESTful devraient naviguer à l'aide des hyperliens fournis et non du chemin de génération, en devinant où un serveur particulier trouve les ressources ... Et après tout, le client ne connaît-il pas déjà l'état de la ressource qu'il vient de créer? sa répétition entraîne un gaspillage de ressources réseau.
ch4mp
1
Pour Créer / Insérer, Statut 201 - CRÉÉ, Emplacement de l'en-tête → localhost: 8080 / salariés / 1 (Voir: ici )
Hassan Tareq

Réponses:

129

Renvoyer l'objet entier sur une mise à jour ne semble pas très pertinent, mais je peux difficilement voir pourquoi retourner l'objet entier lorsqu'il est créé serait une mauvaise pratique dans un cas d'utilisation normal. Cela serait utile au moins pour obtenir l'ID facilement et pour obtenir les horodatages lorsque cela est pertinent. Il s'agit en fait du comportement par défaut obtenu lors de l'échafaudage avec Rails.

Je ne vois vraiment aucun avantage à ne renvoyer que l'ID et à faire une demande GET après, pour obtenir les données que vous auriez pu obtenir avec votre POST initial.

Quoi qu'il en soit, tant que votre API est cohérente, je pense que vous devez choisir le modèle qui correspond le mieux à vos besoins. Il n'y a pas de moyen correct de construire une API REST, imo.

Daniel Perez
la source
26
Je sais que c'est vieux, mais je peux donner un argument convaincant pour utiliser un GET après votre POST. Dans la spécification http / 1.1, tout outil historique peut ignorer les paramètres de cache renvoyés par votre réponse GET ... donc si votre utilisateur utilise le bouton de retour dans le navigateur pour revenir à cette page après l'avoir mis à jour avec le POST, il peut utiliser rassis données mises en cache à partir du GET d'origine. Donc, si vous réutilisez le GET, vous pouvez mettre à jour le cache et obtenir un meilleur instantané de l'apparence de la page quand ils sont partis ...
Shaded
8
@Shaded Si l'API est également conçue pour être utilisée par les applications, votre argument pour faire deux demandes ne tient pas. Là, vous mettez généralement en cache les données en conservant en mémoire des objets d'un type de modèle, ce qui se fait généralement avec la réponse aux requêtes POST. Et en ce qui concerne les navigateurs, la réponse à une demande POST ne fait pas vraiment de mal tant qu'il y a toujours un point de terminaison GET api.
Jeehut
Je souscris à ce que Daniel déclare ici. Même si vous vérifiez des frameworks matures comme Spring Data, ils retournent toujours l'objet entier après l'avoir persisté. Je pense que c'est une bonne pratique, car dans votre client, vous économiserez un aller-retour sur le serveur pour obtenir les mêmes informations
frandevel
205

Le retour du nouvel objet correspond au principe REST de «Interface uniforme - Manipulation des ressources par le biais des représentations». L'objet complet est la représentation du nouvel état de l'objet qui a été créé.

Il existe une excellente référence pour la conception d'API, ici: Meilleures pratiques pour la conception d'une API RESTful pragmatique

Il comprend une réponse à votre question ici: les mises à jour et la création doivent renvoyer une représentation des ressources

Ça dit:

Pour empêcher un consommateur d'API d'avoir à frapper à nouveau l'API pour une représentation mise à jour, demandez à l'API de renvoyer la représentation mise à jour (ou créée) dans le cadre de la réponse.

Cela me semble très pragmatique et cela correspond au principe REST que j'ai mentionné ci-dessus.

grahamesd
la source
6
que diriez-vous de retourner l'ensemble complet des objets pertinents? de cette façon, le tri possible peut être effectué côté serveur, et il facilite l'implémentation
frontale
2
Mais ces meilleures pratiques ne sont pas les meilleures. L'auteur statet que HATEOAS, qui est important au même titre que d'autres principes, ne doit pas être utilisé car "il n'est pas prêt". HATEOAS ne sera jamais "prêt", car tous les principes RESTful ne sont que des principes de conception architecturale, pas une mise en œuvre spécifique. La référence citée concerne la vision de l'auteur sur l'API RESTful, qui n'est pas du tout RESTful en raison de la suppression de HATEOAS. C'est pourquoi ce n'est pas la meilleure référence :)
marcinn
1
@marcinn - vous remarquerez que la question d'origine avait des citations autour de «Best», je suppose parce qu'il y a beaucoup d'opinion dans ce domaine. La référence que j'ai pointée est quelque chose que j'ai trouvé pratique. Si vous avez une meilleure référence, partagez-la. Je suis toujours ouvert à en savoir plus.
grahamesd du
@grahamesd Une implémentation est une chose différente du principe / modèle de conception architecturale. Personne ne peut s'attendre à ce que HATEOAS soit prêt un jour, mais il est possible que quelqu'un crée une implémentation acceptable par beaucoup. Vinay a également écrit sur le mappage des méthodes http aux URL et aux opérations spécifiques (CRUD), a déclaré que la gestion des versions en préfixant les URL est plus pragmatique, a écrit que le filtrage par paramètres de requête est un chemin à parcourir ... c'est bien, mais tout cela a peu à faire faire avec l'architecture RESTful. Il a écrit sur une sorte de contrat. C'est bien pour l'API HTTP, mais ne l'appelez pas RESTful.
marcinn
@grahamesd Voici quelques articles expliquant cela: - medium.com/@andrea.chiarelli/… - restfulapi.net
marcinn