L'archi hexagonale appliquée à un projet dans la vraie vie

Archi hexaquoi 🧐 ?

Normalement, c’est le moment où Orelsan dirait “vous n’avez pas les bases”, alors revenons au début : Qu’est-ce donc cette fameuse archi hexagonale dont tout le monde parle ?

L’archi hexagonale est une architecture logique basée sur les principes SOLID. L’architecture hexagonale place la logique métier au coeur de la technique. Elle permet d’inscrire les structures et règles métier dans le code, sans se soucier des contextes dans lesquels elles vont être appliquées permettant ainsi d’être le plus précis possible dans la traduction des besoins utilisateurs.

Dans l'architecture hexagonale, le système est divisé en plusieurs couches distinctes, qui peuvent être représentées sous forme de cercles concentriques. Au centre se trouve le "domaine", qui contient les règles métier et les entités principales du système. Autour du noyau se trouvent les "ports", qui sont des interfaces définissant les interactions du système avec l'extérieur.

Les ports sont implémentés par des "adaptateurs", qui sont responsables de la connexion entre le domaine et les différentes technologies externes, telles que les bases de données, les services web, etc.

La principale idée de l'architecture hexagonale est de rendre le domaine, indépendant des services externes, de manière à pouvoir le tester et le faire évoluer facilement.

Les adaptateurs sont responsables de la conversion des données provenant des ports vers un format compréhensible par le domaine, et vice versa. Cela permet de réduire la complexité et le couplage du noyau, tout en facilitant les tests unitaires et les tests d'intégration.

Architecture Héxagonale

La mise en place dans un projet

Un de nos projets récents (et toujours en cours) nous a amené à reconstruire un outil métier de traitement des commandes clients qui embrassait l’ensemble de la chaîne de valeur, depuis la création de commande jusqu’à leur comptabilisation. Pour cela nous avions besoin des éléments suivants : une api, une base de données, une authentification d’une part et d’autre part d’avoir un système asynchrone, scalable et plurienvironemental. Notre recherche d’architecture logiciel nous a orienté vers une architecture microservice.

Celle-ci nous a semblé pertinente pour répondre aux problématiques de scalabilité de d’asynchronicitée. Cependant, cela implique d’autres contraintes et d’autres risques. Le plus grand risque étant les incohérences dans les implémentations de nos interfaces avec le domaine. En effet, si vous avez X services différents, ils sont tous libres d’implémenter une version de l’interface de communication, ce qui est un des principes de l’architecture hexagonale. Cela va de pair avec la seconde problématique.

La seconde problématique est l’évolution de ce package “domaine”. Jusqu’à présent, dans une architecture de code, nous utilisions un dépôt de code source par paquet. Ce principe ralentit considérablement la vitesse de développement : si on change la couche logique, il faut mettre à jour un premier dépôt de code, avant de pouvoir faire les modifications dans les autres dépôts de code qui consomment ce paquet. En effet, cela créer une boucle de développement allongée et donc fortement ralentie. Avoir un dépôt de code par package avait pour but de pouvoir faciliter l’intégration des plateformes PaaS pour le déploiement de nos applications.

Cependant, si nous ignorons cette “règle” : un paquet est associé à un dépôt de code source, d’autres possibilités s’ouvrent.

Architecture Hexagonale

Les héros du contrôle de code source

Ceci nous a poussé a créer un monorepository (ou monorepo) où chaque couche est isolée dans son propre dossier tout en restant connectée aux autres couches grâce aux workspaces de npm

La couche domaine est incluse dans la couche infrastructure pour partager les implémentations réelles de chaque service. Chaque processus a son propre dossier pour permettre un déploiement indépendant et une évolutivité horizontale.

On se retrouve avec un seul code source qui architecture les différentes briques et les partage. Nous avons les briques suivantes :

  • Domain : il s’agit du coeur fonctionnel de métier dont on parlait précédemment et qui est indépendant
  • Infrastructure : l’implémentation des méthodes du domaine que l’on va partager entre tous les différents microservices. Ses dépendances sont le domaine, les bases de données et les autres services avec lesquels on est susceptible d’interagir
  • API, Workers, Script… : tout les différents processus qui correspondent au côté “déploiement” de notre application. Il s’agit de tout les processus et microservices qui seront déployés. Ceux-ci dépendent du domaine et de l’infrastructure.
  • Serverless : c’est le dossier qui s’occupe de faire le déploiement de tout ces services déclarés précédemment et dépend donc de tout les dossiers précédents.

On retrouve ainsi l’avantage d’avoir un code métier et infrastructure partagée, tout en permettant d’avoir des services et une exécution en mode microservices.

On a également un développement facilité, les changements faits dans le domaine sont directement propagés vers les autres couches et assurent une cohérence globale du projet.

Conclusion

En conclusion, l’architecture que nous avons mis en place, nous semble intéressante pour répondre aux différents besoins d’évolutivités et de scalabilités que l’on peut rencontrer dans nos projets actuels. Cette architecture nous permet également d’assurer la qualité et la validité de nos développements. Il serait intéressant d’explorer les pistes pour intégrer les interfaces graphiques afin d’assurer une cohérence sur le projet de bout en bout.