J'ai rencontré ce même problème encore et encore et je n'ai pas trouvé de solution que je ressentais vraiment comme optimale.
Dites dans une application, vous avez une liste ordonnée et vous laissez l'utilisateur changer cet ordre par glisser-déposer ou quelque chose. Vous souhaitez que les modifications de l'ordre persistent. Comment modélisez-vous cela?
Comment dois-je concevoir un service reposant d'une ressource de liste ordonnée?
En particulier, comment concevoir le list
et le item
modèle d'une ressource reposante? La conception la plus courante que j'ai vue est l' item
entité ayant une propriété order
ou position
. Une autre approche que j'ai entendue est une liste doublement liée sur les articles.
Qu'est-ce qu'une approche qui n'écrit pas trop dans la base de données et qui est généralement rapide à mettre à jour et à lire pour les clients? Comment les points de terminaison doivent-ils être exposés?
la source
Réponses:
La représentation d'une liste ordonnée est l'un des problèmes difficiles des bases de données relationnelles. L'ajout d'une propriété de position à la relation liste-appartenance est le moyen le plus courant de le faire, car vous pouvez facilement récupérer la liste ordonnée en l'ajoutant
ORDER BY position
à votre requête SQL et parce que vous pouvez facilement insérer des éléments au milieu de la liste en faisant la moyenne de la valeurs du membre de liste précédent et suivant, en supposant que la position est un flottant plutôt qu'un entier.L'utilisation de listes doublement liées doit être évitée, car il est facile de rendre accidentellement les liens incohérents et de se retrouver avec un graphique ou un arbre cyclique à la place.
Cependant, les API RESTful ne souffrent pas des restrictions des bases de données relationnelles. Vous pouvez simplement faire quelque chose qui semble naturel, plutôt que d'utiliser un hack comme une propriété de position.
Si vous n'avez que quelques centaines d'éléments dans la liste, transférez simplement la liste entière dans une demande. En supposant que nous voulons réorganiser
[1, 2, 3, 4]
où les membres de la liste sont des identifiants, nous pourrionsLe backend peut ensuite traduire cela dans la technologie de base de données que vous utilisez, mais l'utilisateur de l'API n'a pas à prendre en compte ces détails.
Si la liste est grande et que les éléments sont généralement demandés individuellement, vous pouvez autoriser un index dans l'url:
Si vous êtes dans HATEOAS, la réponse peut inclure des liens précédent / suivant pour simplifier la navigation, si la ressource est généralement consommée comme ça. Cependant, cela ne signifie pas nécessairement que votre base de données contient également cette liste doublement liée.
Si la liste est très volumineuse, vous souhaiterez peut-être exposer des
ArrayList
opérations similaires à /insert
ou . Je pourrais imaginer un appel commepush
append
Si la réorganisation est un cas d'utilisation courant et que la réorganisation doit être validée immédiatement, vous pouvez proposer un point de terminaison approprié dans votre API:
Si la liste réorganisée doit être validée explicitement, il sera plus facile de transférer la nouvelle commande en tant que document JSON, voir ci-dessus.
Maintenant, ce n'est pas tout à fait vrai que vous pouvez voir votre API comme complètement séparée de la technologie de base de données que vous utilisez. Cependant, il est préférable de garder l'API externe aussi libre que possible des détails d'implémentation. Si une réorganisation touche environ 30 lignes juste pour mettre à jour une colonne d'ordre entier, ce n'est pas grave. Faites simplement la chose la plus simple possible et mettez toujours à jour toute la liste. Si votre évolutivité nécessite une utilisation plus sophistiquée de votre base de données, préférez capturer cette sophistication dans le backend, où il est plus facile de maintenir la cohérence.
la source
Je pense que la viabilité des différentes approches dépend fortement de la base de données sous-jacente utilisée.
Cette approche a suggéré de déplacer un article dans la commande:
Cela peut être soumis à des conditions de concurrence, sauf si vous avez une transactionnalité SERIALISABLE. Le niveau par défaut de READ_COMMITTED dans la plupart des bases de données n'éliminera pas une condition de concurrence critique!
En fait, je pense que dans la plupart des cas - tant que la liste est relativement petite - alors l'approche de remplacement de la liste complète a moins de problèmes avec les conditions de concurrence et ne peut pas corrompre les données. Si l'ensemble des éléments a changé depuis que le client a fait la demande, vous pouvez renvoyer un 409 (Conflit).
Il souffre des dernières victoires en écriture, mais c'est vrai de littéralement N'IMPORTE QUELLE api. Quelle que soit l'API que vous implémentez, un autre client peut avoir mis à jour la chose pendant que vous consultez une page.
la source