web-dev-qa-db-fra.com

Manière RESTful de créer plusieurs éléments en une seule demande

Je travaille sur un petit programme client-serveur pour récupérer les commandes. Je veux le faire d'une manière "REST (ful)".

Ce que je veux faire, c'est:

Récupérer toutes les lignes de commande (produit et quantité) et envoyer la commande complète au serveur

Pour le moment, je vois deux options pour ce faire:

  1. Envoyez chaque ligne de commande au serveur: POST qty and product_id

En fait, je ne veux pas le faire parce que je veux limiter le nombre de demandes au serveur, donc option 2:

  1. Collectez toutes les lignes de commande et envoyez-les au serveur en même temps.

Comment dois-je implémenter l'option 2? Voici quelques idées que j'ai: Envelopper toutes les lignes de commande dans un objet JSON et l'envoyer au serveur ou utiliser un tableau pour publier les lignes de commande.

Est-ce une bonne idée ou une bonne pratique de mettre en œuvre l'option 2, et si oui, comment dois-je le faire?.

Quelle est la bonne pratique?

115
Paul

Je crois qu'une autre façon correcte d'aborder ce problème serait de créer une autre ressource qui représente votre collection de ressources. Par exemple, imaginez que nous avons un point de terminaison comme /api/sheep/{id} et nous pouvons POST to /api/sheep pour créer une ressource ovine.

Maintenant, si nous voulons prendre en charge la création en bloc, nous devrions envisager une nouvelle ressource de troupeau à /api/flock (ou /api/<your-resource>-collection si vous manquez un nom plus significatif). N'oubliez pas que les ressources n'ont pas besoin d'être mappées à votre base de données ou à vos modèles d'application. Il s'agit d'une idée fausse courante.

Les ressources sont une représentation de niveau supérieur, sans rapport avec vos données. Opérer sur une ressource peut avoir des effets secondaires importants, comme déclencher une alerte sur un utilisateur, mettre à jour d'autres données connexes, lancer un processus de longue durée, etc. Par exemple, nous pourrions mapper un système de fichiers ou même unix ps comme une REST.

Je pense qu'il est prudent de supposer que l'exploitation d'une ressource peut également signifier la création de plusieurs autres entités comme effet secondaire.

65
miguelcobain

Bien que les opérations en masse (par exemple, la création par lots) soient essentielles dans de nombreux systèmes, elles ne sont pas formellement traitées par le style d'architecture RESTful.

J'ai trouvé que POSTER une collection comme vous l'avez suggéré fonctionne essentiellement, mais des problèmes surviennent lorsque vous devez signaler des échecs en réponse à une telle demande. Ces problèmes sont pires lorsque plusieurs échecs se produisent pour différentes causes ou lorsque le serveur ne prend pas en charge les transactions. Ma suggestion est que s'il n'y a pas de problème de performances, par exemple lorsque le fournisseur de services est sur le LAN (pas WAN) ou que les données sont relativement petites, cela vaut la peine d'envoyer 100 POST Demandes simples au serveur. Restez simple, commencez par des demandes distinctes et si vous avez un problème de performances, essayez d'optimiser.

43
LiorH

Facebook explique comment procéder: https://developers.facebook.com/docs/graph-api/making-multiple-requests

Demandes groupées simples

L'API par lots prend en charge un tableau de requêtes HTTP logiques représentées comme des tableaux JSON - chaque requête a une méthode (correspondant à la méthode HTTP GET/PUT/POST/DELETE etc.), un relative_url (la partie de l'URL après graph.facebook. com), un tableau d'en-têtes facultatif (correspondant aux en-têtes HTTP) et un corps facultatif (pour les demandes POST et PUT). L'API Batch renvoie un tableau de réponses HTTP logiques représentées comme des tableaux JSON - chaque réponse a un code d'état, un tableau d'en-têtes facultatif et un corps facultatif (qui est une chaîne codée JSON).

10
rwitzel

Votre idée me semble valable. La mise en œuvre est une question de votre préférence. Vous pouvez utiliser JSON ou simplement des paramètres pour cela (tableau "order_lines []") et faire

POST /orders

Puisque vous allez créer plus de ressources à la fois en une seule action (l'ordre et ses lignes), il est vital de valider chacune d'entre elles et de les enregistrer uniquement si toutes réussissent la validation, c'est-à-dire. vous devez le faire dans une transaction.

8
Milan Novota

Je suppose qu'il vaut mieux envoyer des demandes séparées dans connexion unique . Bien sûr, votre serveur Web doit le prendre en charge

6
zakovyrya

J'ai lutté contre cela récemment, et voici ce vers quoi je travaille.

Si un POST qui ajoute plusieurs ressources réussit, retourne un 200 OK (je considérais un 201, mais l'utilisateur ne finit pas par atterrir sur une ressource qui a été créée) avec une page qui affiche toutes les ressources qui ont été ajoutées, en lecture seule ou modifiables. Par exemple, un utilisateur peut sélectionner et POST plusieurs images dans une galerie à l'aide d'un formulaire ne comprenant qu'une seule entrée de fichier. Si la demande POST réussit dans son intégralité, l'utilisateur est présenté avec un ensemble de formulaires pour chaque représentation de ressource d'image créée qui lui permet de spécifier plus de détails sur chacun (nom, description, etc.).

Si une ou plusieurs ressources ne sont pas créées, le gestionnaire POST abandonne tout traitement et ajoute chaque message d'erreur individuel à un tableau. Ensuite, un conflit 419 est renvoyé et l'utilisateur est routé à une page d'erreur 419 Conflict qui présente le contenu du tableau d'erreurs, ainsi qu'un retour au formulaire qui a été soumis.

5
Eric Fuller

Vous ne voudrez pas envoyer les en-têtes HTTP pour 100 lignes de commande. Vous ne souhaitez pas non plus générer plus de demandes que nécessaire.

Envoyez la commande entière dans un objet JSON au serveur, à: serveur/commande ou serveur/commande/nouveau. Renvoie quelque chose qui pointe vers: server/order/order_id

Pensez également à utiliser CRÉER PUT au lieu de POST

0
Cheery