Nous construisons une architecture de microservice pour nos projets, avec principalement des applications Symfony frontales interagissant avec des API RESTful dorsales.
Le problème est que cette approche brise la gestion des entités Symfony en s'appuyant fortement sur Doctrine avec base de données. Lorsque Symfony gère généralement des entités avec Doctrine, automatisant la plupart du travail, cela ne peut pas être reproduit facilement lorsque nous devons accéder à des données externes à partir des API.
Par exemple, avec une entité Client:
- En utilisant Doctrine, il suffit de définir notre classe Client, et il est désormais facile de créer, mettre à jour, récupérer nos clients
- En utilisant l'approche API REST, les clients sont accessibles via l'API, mais nous avons beaucoup de travail pour définir comment le client est créé (POST), mis à jour (PUT), récupéré (GET), etc.
A noter que les clients sont utilisés par plusieurs applications, pas seulement l'application frontale, d'où l'API dédiée.
Devrions-nous créer des classes avec des méthodes de type entité masquant la complexité des appels d'API, importer toutes les données d'API localement et y accéder via Doctrine, ou de toute autre manière?
Réponses:
J'ai créé un projet basé sur symfony qui utilise une API externe (JSON); j'ai créé une bibliothèque cliente indépendante ("bibliothèque cliente" - un logiciel, un package de compositeur), avec son propre ensemble d'entités (POPO); il s'intègre au framework à l'aide des interfaces fournies par Symfony (par exemple, en créant simplement un fournisseur d'utilisateurs personnalisé ).
Le client effectue des appels http "en arrière-plan" - ce qui est important pour les futures capacités de test. Vous ne voulez pas exposer la façon dont vous communiquez avec votre source de données et vous ne voulez pas non plus que vos tests s'appuient sur une API en direct.
Interface de bibliothèque client (exemple à quoi elle peut ressembler):
La bibliothèque cliente utilise en interne Guzzle pour la communication et le composant Doctrine Cache pour la mise en cache des résultats. Le mappage entre les objets d'entité et json a été fait par des mappeurs, qui une fois écrits - ne changeaient pas très souvent (ou événement du tout). Dans ce cas, je suggère d'utiliser le JMS Serializer pour une transformation automatisée vers et depuis JSON (je suppose que vous utilisez JSON).
Vous aurez besoin d'un bon mécanisme de mise en cache et d'un stockage local, comme Redis. Faire des appels api sur chaque demande d'application va tuer votre serveur et ralentir considérablement votre application. Il est très important de comprendre le fonctionnement des caches http. Si votre API n'utilise pas les en-têtes de mise en cache (ou l'utilise de manière obscure), il sera très difficile et consommateur de ressources de suivre les modifications.
Vous voudrez également réfléchir à la façon dont le client devrait se comporter en cas de rupture de la connexion - le client devrait-il utiliser des données bloquées? Ce serait une bonne idée d'utiliser un serveur proxy entre votre application et l'API. Dans ce cas, le proxy (comme Varnish) pourrait accélérer vos demandes et également actualiser les données bloquées en arrière-plan sans ralentir votre application. Il gardera également votre site Web en ligne en cas de défaillance de l'API. Vous ne pourrez peut-être pas écrire de données entre-temps, mais vos utilisateurs pourront toujours parcourir les données mises en cache.
Et en parlant de Doctrine, voir la " Loi de l'instrument ".
la source
Doctrine est une couche d'accès à la base de données. Vous ne voulez pas accéder à une base de données, mais aux API. Vous pouvez toujours créer une entité, mais comme un simple objet qui n'a pas à étendre notre implémentation (un popo). Il devrait avoir un référentiel qui implémente toutes les méthodes CRUD. Dans ce cas, appelle l'API au lieu de la base de données. Je créerais une interface pour ça. Il n'est pas nécessaire que votre application soit différente, sauf que vous devez tenir compte partout où un micro service peut ne pas répondre.
la source
Pour info, il existe désormais un composant HttpClient pour la v4.3.
https://symfony.com/blog/new-in-symfony-4-3-httpclient-component
la source