Attention: gros post, quelques opinions, vague "faites ce qui vous convient le mieux" conclusion
Généralement, ceci est utilisé pour implémenter une «architecture hexagonale» autour de votre base de données. Vous pouvez avoir des applications Web, des applications mobiles, des applications de bureau, des importateurs en masse et un traitement en arrière-plan qui consomment votre base de données de manière uniforme. Vous pouvez certainement accomplir la même chose dans une certaine mesure en écrivant une bibliothèque riche pour accéder à votre base de données et en faisant en sorte que tous vos processus l'utilisent. Et en effet, si vous êtes dans un petit magasin avec un système très simple, c'est probablement une meilleure voie à suivre; C'est une approche plus simple et si vous n'avez pas besoin des fonctionnalités avancées d'un système plus complexe, pourquoi payer pour la complexité? Toutefois, si vous travaillez avec un grand ensemble sophistiqué de systèmes qui doivent tous interagir avec votre base de données à grande échelle, il existe
Indépendance et maintenance de la plateforme
Si vous avez une base de données et que vous écrivez une bibliothèque Python pour interagir avec cette base de données, et que tout le monde l'utilise pour interagir avec la base de données, c'est génial. Mais disons que vous devez soudainement écrire une application mobile et que cette application mobile doit désormais également parler à la base de données. Et vos ingénieurs iOS n'utilisent pas Python et vos ingénieurs Android n'utilisent pas Python. Peut-être que les gars d'iOS veulent utiliser les langages d'Apple et les ingénieurs d'Android veulent utiliser Java. Ensuite, vous seriez bloqué à écrire et à maintenir votre bibliothèque d’accès aux données dans 3 langues différentes. Peut-être que les développeurs iOS et Android décident d’utiliser quelque chose comme Xamarin pour maximiser le code qu’ils peuvent partager. Parfait, sauf que vous allez probablement devoir porter votre bibliothèque d'accès aux données au format .NET. Et puis votre entreprise vient d’acheter une autre entreprise qui ' L'application Web de s est un produit disparate mais lié, et l'entreprise souhaite intégrer certaines des données de la plate-forme de votre société à la plate-forme de la filiale récemment acquise. Seul problème: la filiale était une start-up et a décidé d'écrire l'essentiel de son application dans Dart. De plus, pour une raison quelconque (probablement indépendante de votre volonté), l'équipe mobile qui pilotait Xamarin a décidé que ce n'était pas pour eux, et qu'ils préféraient utiliser les outils et les langages spécifiques aux appareils mobiles pour lesquels ils développeraient. Mais pendant que vous en étiez dans cette phase, votre équipe avait déjà livré une grande partie de votre bibliothèque d’accès aux données dans .NET, et une autre équipe de la société écrivait des éléments d’intégration dingues Salesforce et a décidé de faire tout cela dans .NET car était déjà une bibliothèque d'accès aux données pour.
Alors maintenant, à cause d’une tournure très réaliste des événements, votre bibliothèque d’accès aux données est écrite en Python, .NET, Swift, Java et Dart. Ils ne sont pas aussi beaux que vous le souhaiteriez. Vous ne pouvez pas utiliser un ORM aussi efficacement que vous le souhaitez, car chaque langue possède des outils ORM différents, vous avez donc dû écrire plus de code que vous n'auriez souhaité. Et vous n'avez pas été en mesure de consacrer autant de temps que vous l'auriez souhaité à chaque incarnation, car il y en a cinq. Et la version Dart de la bibliothèque est particulièrement poilue parce que vous deviez rouler vous-même vos données transactionnelles, car les bibliothèques et le support technique n’étaient tout simplement pas au rendez-vous. Vous avez essayé de faire valoir que, pour cette raison, l’application Dart ne devait disposer que de fonctionnalités en lecture seule pour votre base de données, mais l'entreprise avait déjà décidé que toutes les fonctionnalités envisagées en valaient la peine. Et il s'avère qu'il y a un bogue dans la logique de validation qui existe dans toutes ces incarnations de votre bibliothèque d'accès aux données. Maintenant, vous devez écrire des tests et du code pour corriger ce bogue dans toutes ces bibliothèques, obtenir des critiques de code pour toutes les modifications apportées à ces bibliothèques, obtenir un contrôle de qualité sur toutes ces bibliothèques et publier vos modifications sur tous les systèmes en utilisant toutes les versions. ces bibliothèques. Pendant ce temps, vos clients sont mécontents et ont adopté Twitter, réunissant des combinaisons de vulgarités que vous n'auriez jamais imaginées imaginables, sans parler du produit phare de votre entreprise. Et le responsable du produit décide de ne pas être du tout conscient de la situation.
S'il vous plaît, comprenez que dans certains environnements, l'exemple ci-dessus est tout sauf artificiel. Tenez également compte du fait que cette séquence d'événements peut se dérouler au cours de quelques années. Généralement, lorsque vous arrivez au point où architectes et hommes d’affaires commencent à parler de la connexion d’autres systèmes à votre base de données, c’est à ce moment-là que vous allez vouloir «placer une API REST devant la base de données» sur votre feuille de route. Pensez si, dès le début, quand il était clair que cette base de données allait commencer à être partagée par quelques systèmes, un API de service Web / REST était placé devant elle. La correction de votre bogue de validation serait beaucoup plus rapide et facile car vous le faites une fois au lieu de cinq fois. Et publier le correctif serait beaucoup plus facile à coordonner, car vous
TLDR; Il est plus facile de centraliser la logique d'accès aux données et de maintenir des clients HTTP très minces que de distribuer la logique d'accès aux données à chaque application devant accéder aux données. En fait, votre client HTTP peut même être généré à partir de méta-données. Dans les grands systèmes, l’API REST vous permet de gérer moins de code
Performance et évolutivité
Certaines personnes peuvent penser que le fait de communiquer directement avec la base de données au lieu de passer par un service Web est plus rapide. Si vous n'avez qu'une seule application, c'est certainement vrai. Mais dans les grands systèmes, je ne suis pas d'accord avec le sentiment. Éventuellement, à un certain niveau d’échelle, il sera très utile de mettre une sorte de cache en face de la base de données. Vous utilisez peut-être Hibernate et souhaitez installer une grille Infinispan en tant que cache L2. Si vous disposez d'un cluster de 4 serveurs robustes pour héberger votre service Web séparément de vos applications, vous pouvez vous permettre de disposer d'une topologie intégrée avec réplication synchrone activée. Si vous essayez de placer cela sur un cluster de 30 serveurs d'applications, l'activation de la réplication dans cette configuration sera trop lourde. Vous devrez soit exécuter Infinispan en mode distribué ou dans une sorte de topologie dédiée, et soudainement, Hibernate devra sortir sur le réseau pour pouvoir lire dans le cache. De plus, Infinispan ne fonctionne qu'en Java. Si vous avez d'autres langues, vous aurez besoin d'autres solutions de mise en cache. La surcharge réseau de devoir passer de votre application à votre service Web avant d’atteindre la base de données est rapidement compensée par la nécessité d’utiliser des solutions de mise en cache beaucoup plus compliquées qui viennent généralement avec une charge supplémentaire.
En outre, cette couche HTTP de votre API REST fournit un autre mécanisme de mise en cache précieux. Les serveurs de votre API REST peuvent placer des en-têtes de mise en cache sur leurs réponses. Ces réponses peuvent être mises en cache au niveau de la couche réseau, qui évolue exceptionnellement bien. Dans une petite configuration, avec un ou deux serveurs, le mieux est simplement d’utiliser un cache en mémoire dans l’application lorsque celle-ci communique avec la base de données, mais dans une grande plate-forme avec de nombreuses applications exécutées sur de nombreux serveurs, vous réseau pour gérer votre mise en cache, car une fois correctement configuré, quelque chose comme calmar ou vernis ou nginx peut évoluer à des niveaux insensés sur un matériel relativement petit. Des centaines de milliers ou des millions de requêtes par seconde de débit coûtent beaucoup moins cher à partir d'un cache HTTP que d'un serveur d'applications ou d'une base de données.
En plus de cela, le fait d'avoir une tonne de clients pointés sur votre base de données, au lieu de les faire tous pointer sur quelques serveurs pointant vers la base de données, peut rendre le réglage de la base de données et du pool de connexions beaucoup plus difficile. En général, la majeure partie de la charge de travail réelle d'un serveur d'applications est constituée d'applications. Attendre que les données reviennent de la base de données prend souvent beaucoup de temps, mais coûte généralement très peu en calcul. Vous aurez peut-être besoin de 40 serveurs pour gérer la charge de travail de votre application, mais vous n'avez probablement pas besoin de 40 serveurs pour orchestrer l'extraction des données de la base de données. Si vous dédiez cette tâche à un service Web, celui-ci s'exécutera probablement sur beaucoup moins de serveurs que le reste de l'application, ce qui signifie que vous aurez besoin de beaucoup moins de connexions à la base de données. Ce qui est important, car les bases de données ne
TLDR; Il est plus facile d'ajuster, de mettre à l'échelle et de mettre en cache l'accès à vos données lorsque cela se produit dans un seul service Web dédié plutôt que dans de nombreuses applications utilisant différentes langues et technologies.
Dernières pensées
S'il vous plaît, ne quittez pas cette pensée "Oh wow, je devrais toujours utiliser des API REST pour obtenir mes données" ou "Cet idiot essaie de dire que nous le faisons mal parce que notre application Web communique directement avec la base de données, mais nos affaires fonctionnent bien! " . Ce que je veux surtout dire, c’est que différents systèmes et différentes entreprises ont des exigences différentes; Dans de nombreux cas, placer une API REST en face de votre base de données n’a vraiment aucun sens. C'est une architecture plus compliquée qui nécessite de justifier cette complexité. Mais lorsque la complexité est garantie, l’API REST présente une foule d’avantages. Être capable de peser les différentes préoccupations et de choisir la bonne approche pour votre système est ce qui fait un bon ingénieur.
De plus, si l'API REST vous empêche de déboguer des choses, il y a probablement quelque chose qui ne va pas ou qui manque dans cette image. Je ne crois pas que le fait d'avoir cette couche d'abstraction ajoutée rend intrinsèquement plus difficile le débogage. Lorsque je travaille avec de grands systèmes n-tiers, j'aime m'assurer que le contexte de journalisation est distribué. Peut-être que lorsqu'un utilisateur lance une demande, générez un GUID pour cette demande et enregistrez le nom d'utilisateur de cet utilisateur et la demande qu'il a faite. Ensuite, transmettez ce GUID pendant que votre application parle à d'autres systèmes. Avec une agrégation et une indexation appropriées des journaux, vous pouvez interroger toute la plate-forme sur l'utilisateur signalant le problème. Vous avez ainsi la possibilité de visualiser toutes ses actions. Elles parcourent ensuite le système pour identifier rapidement les dysfonctionnements. Encore une fois, c'est une architecture plus compliquée,
Sources:
http://alistair.cockburn.us/Hexagonal+architecture
https://github.com/brettwooldridge/HikariCP/wiki/About-Pool-Sizing