Bulk Collection Manipulation via une API REST (RESTful)

Je voudrais des conseils sur la conception d’une API REST qui permettra aux clients d’append / supprimer un grand nombre d’objects à une collection efficacement.

Via l’API, les clients doivent pouvoir append des éléments à la collection et en supprimer des éléments, ainsi que manipuler des éléments existants. Dans de nombreux cas, le client souhaite effectuer des mises à jour groupées de la collection, par exemple en ajoutant 1 000 éléments et en supprimant 500 éléments différents. On a l’impression que le client devrait pouvoir le faire en une seule transaction avec le serveur, plutôt que d’exiger 1000 requêtes POST et 500 DELETE distinctes.

Quelqu’un at-il des informations sur les meilleures pratiques ou conventions pour y parvenir?

Ma pensée actuelle est que l’on devrait pouvoir mettre un object représentant le changement dans l’URI de la collection, mais cela semble en contradiction avec la RFC HTTP 1.1 , qui semble suggérer que les données envoyées dans une requête PUT doivent être interprétées indépendamment du données déjà présentes à l’URI. Cela implique que le client devrait envoyer une description complète du nouvel état de la collection en une seule fois, ce qui pourrait bien être beaucoup plus important que le changement, ou même être plus que ce que le client saurait lors de la demande.

Évidemment, je serais heureux de s’écarter de la RFC si nécessaire, mais je préférerais le faire de manière conventionnelle si une telle convention existe.

Vous pouvez penser à la tâche de changement comme une ressource en soi. Donc, vous êtes vraiment en train de mettre un seul object, qui est un object Bulk Data Update. Peut-être a-t-il un nom, un propriétaire et une grosse tâche de CSV, XML, etc. qui doivent être analysés et exécutés. Dans le cas du format CSV, vous pouvez également identifier le type d’object représenté dans les données CSV.

Répertorier les travaux, append un travail, afficher le statut d’un travail, mettre à jour un travail (probablement pour le démarrer / l’arrêter), supprimer un travail (l’arrêter s’il est en cours d’exécution) etc. Ces opérations correspondent facilement à une conception d’API REST.

Une fois que vous avez ceci en place, vous pouvez facilement append différents types de données que votre programme de mise à jour de données en bloc peut gérer, peut-être même mélangés dans la même tâche. Il n’y a pas besoin d’avoir cette même API dupliquée sur toute votre application pour chaque type de chose que vous souhaitez importer, autrement dit.

Cela se prête également très facilement à une implémentation de tâche d’arrière-plan. Dans ce cas, vous souhaiterez probablement append des champs aux objects de tâche individuels qui permettent au client API de spécifier comment ils veulent être notifiés (une URL qu’ils veulent que vous obteniez lorsque cela est fait ou leur envoyez un courrier électronique, etc.) .

Oui, PUT crée / écrase, mais ne met pas à jour partiellement.

Si vous avez besoin d’une sémantique de mise à jour partielle, utilisez PATCH. Voir http://greenbytes.de/tech/webdav/draft-dusseault-http-patch-14.html .

Vous devez utiliser AtomPub . Il est spécifiquement conçu pour gérer des collections via HTTP. Il pourrait même y avoir une implémentation pour la langue de votre choix.

Pour les POST, au moins, il semble que vous devriez pouvoir afficher une liste URL et que le corps de la requête contienne une liste de nouvelles ressources au lieu d’une nouvelle ressource unique.

Si je comprends bien, REST signifie transfert d’état représentationnel, vous devez donc transférer l’état du client au serveur.

Si cela signifie trop de données dans les deux sens, vous devrez peut-être modifier votre représentation. Une structure de collectionChange fonctionnerait, avec une série de suppressions (par identifiant) et d’ajouts (avec des représentations xml complètes intégrées), POSTed à une URL d’interface de traitement. L’implémentation de l’interface peut choisir sa propre méthode pour les suppressions et les ajouts côté serveur.

La version la plus pure serait probablement de définir les éléments par URL, et la collection contiendrait une série d’URL. La nouvelle collection peut être PUT après les modifications du client, suivie d’une série de PUT des éléments ajoutés, et peut-être d’une série de suppressions si vous souhaitez réellement supprimer les éléments du serveur plutôt que de simplement les supprimer de cette liste.

Vous pourriez introduire la méta-représentation d’éléments de collection existants qui n’ont pas besoin de transférer l’intégralité de leur état. Dans un code abstrait, votre mise à jour pourrait ressembler à ceci:

  {éléments existants 1-100}
 {nouvel élément foo avec les valeurs "bar", "baz"}
 {élément existant 105}
 {nouvel élément foobar avec des valeurs "bar", "foo"}
 {éléments existants 110-200} 

L’ajout (et la modification) d’éléments se fait en définissant leurs valeurs, la suppression d’éléments est effectuée en ne mentionnant pas la nouvelle collection et la réorganisation des éléments se fait en spécifiant la nouvelle commande (si l’ordre est stocké).

De cette façon, vous pouvez facilement représenter toute la nouvelle collection sans avoir à retransmettre la totalité du contenu. L’utilisation d’un en If-Unmodified-Since tête If-Unmodified-Since permet de s’assurer que votre idée du contenu correspond bien à l’idée du serveur (de sorte que vous ne supprimiez pas accidentellement des éléments dont vous ne saviez tout simplement pas au moment de la soumission).