L’article propose une solution pour gérer les transactions en couche applicative dans une architecture hexagonale, sans dépendre de l’infrastructure comme Doctrine. L’idée centrale est d’introduire un port TransactionManagerInterface dans l’application, implémenté par un adaptateur Doctrine qui utilise wrapInTransaction() pour encapsuler les opérations dans une transaction unique. Cela permet d’éviter les problèmes de cohérence, comme des modifications partielles en cas d’échec, en regroupant plusieurs opérations (persistance, mise à jour) dans un bloc atomique.
L’auteur illustre le problème avec un cas concret : la création d’une commande et la mise à jour simultanée des stocks. Sans gestion centralisée, chaque appel à flush() (via add() ou update()) crée une transaction implicite, risquant des incohérences si une étape échoue. La solution repose sur un service applicatif (OrderService) qui dépend uniquement des interfaces de domaine et du TransactionManagerInterface, isolant ainsi la logique métier des détails d’infrastructure.
Enfin, l’implémentation montre comment le TransactionManager utilise les mécanismes natifs de Doctrine pour gérer les transactions de manière robuste, y compris les erreurs PHP, tout en maintenant une séparation claire des responsabilités. Les méthodes add() et update() des repositories doivent éviter d’appeler flush() directement pour préserver l’intégrité transactionnelle.
L’article souligne que Symfony, souvent perçu comme un framework monolithique, peut être utilisé comme un simple adapter pour isoler la logique métier du code lié au framework. L’auteur explique que, malgré une architecture apparente propre (contrôleurs légers, services organisés), une application Symfony mature reste profondément couplée à Doctrine et Symfony, ce qui limite sa maintenabilité et sa portabilité. Il illustre ce problème par un exemple concret où l’entité Order gère directement des calculs de taxes via des annotations Doctrine, montrant ainsi une dépendance implicite au framework.
Pour résoudre ce couplage, l’auteur propose une architecture en trois couches : le Domain (PHP pur, sans dépendances externes), l’Application (cas d’utilisation et interfaces) et l’Infrastructure (adaptateurs Symfony/Doctrine). Cette séparation stricte permet de tester et faire évoluer le domaine indépendamment du framework. Un contrôle CI vérifie que le dossier Domain/ n’importe jamais de classes Symfony ou Doctrine, garantissant ainsi l’étanchéité de l’architecture.
Enfin, l’auteur compare cette approche à celle d’un projet Laravel, insistant sur le fait que Symfony, comme tout framework, doit être traité comme un outil d’infrastructure et non comme le cœur de l’application. L’objectif est de rendre le code plus résilient aux changements technologiques tout en conservant la puissance de Symfony pour les aspects HTTP, persistance ou messagerie.
L’article explique comment implémenter une architecture hexagonale dans Symfony 7 pour séparer clairement les couches métier et infrastructure, en combinant des motifs DDD et une approche pilotée par événements. L’idée centrale est de placer le domaine au centre, indépendant du framework, tandis que les dépendances externes (Symfony, Doctrine, etc.) s’interfacent via des ports définis par le domaine. Cela permet une meilleure testabilité, évolutivité et flexibilité, comme illustré par un exemple concret de structure de code organisée en trois couches (Domain, UserInterface, Infrastructure).
L’auteur souligne les limites des architectures traditionnelles en couches, où les services deviennent des "classes-dieu" et les tests complexes. En adoptant cette approche, les commandes, requêtes et événements sont gérés de manière isolée, facilitant les changements techniques (ex : remplacer Doctrine par MongoDB) sans impacter la logique métier. L’intégration de Symfony Messenger renforce le caractère événementiel, permettant une communication asynchrone entre les composants.
Enfin, l’article aborde brièvement la séparation des lectures et écritures (CQRS), bien que le détail soit tronqué. L’accent est mis sur la praticité : une implémentation concrète, adaptable, qui évite les pièges des architectures monolithiques tout en restant compatible avec les outils Symfony existants.
Tout est dans le titre
Tout est dans le titre
Tout est dans le titre
Tout est dans le titre
Tout est dans le titre... les commentaires sont intéressants aussi ^^