L’architecture hexagonale, aussi appelée « Ports and Adapters », est un style d’architecture logicielle qui encourage une séparation stricte entre la logique métier (au centre de l’application) et les interactions avec le monde extérieur (systèmes, bases de données, APIs, etc.). Ce paradigme est très prisé dans le développement d’applications modulaires et testables. Mais peut-il s’appliquer efficacement à l’intégration de données dans un environnement Azure ?
C’est une question légitime, car l’intégration de données est historiquement dominée par des pipelines ETL ou ELT, souvent orchestrés via des outils low-code/no-code ou des scripts ciblés. Pourtant, la montée en complexité des besoins métiers, l’émergence des architectures orientées événements et les exigences de maintenabilité incitent à reconsidérer notre approche.
Explorons donc trois dimensions clés pour évaluer la pertinence de l’architecture hexagonale dans ce contexte.
L’architecture hexagonale impose une distinction nette entre le domaine (le « coeur » de l’application) et tout ce qui relève de l’interaction technique : lecture/écriture de données, appels à des APIs, manipulation de fichiers, etc. Dans un contexte Azure, cela signifie que la logique de transformation, de validation, de déduplication ou d’enrichissement est isolée dans une bibliothèque ou un module de domaine, totalement indépendant des services Azure (Blob Storage, Event Hub, SQL Database, etc.).
Cette séparation favorise une meilleure compréhension fonctionnelle de l’application. Elle permet à des développeurs ou analystes de se concentrer sur le « quoi » sans être distraits par le « comment ».
Quand l’infrastructure évolue (ex. passage d’un stockage SQL à Cosmos DB, ajout d’un canal Kafka), il est fréquent de devoir tout réécrire dans une architecture couplée. L’architecture hexagonale résout ce problème en cloisonnant les parties sensibles au changement.
Un adaptateur change ? Ce n’est qu’une classe à réimplémenter ou à déplacer, tant que les interfaces (ports) restent stables. Cette souplesse devient un atout majeur dans les projets d’intégration multi-clients ou multi-environnements.
Chaque module a une responsabilité claire : la logique métier définit ce qui doit être fait, les adaptateurs se chargent de le réaliser techniquement. Cette structure permet une meilleure lecture du code, une meilleure documentation naturelle des responsabilités, et rend les revues de code plus efficaces.
Cela facilite également le travail d’équipes pluridisciplinaires : les experts fonctionnels peuvent se concentrer sur la logique métier sans craindre de casser la partie technique.
En centralisant la logique métier dans un domaine pur (sans dépendance à Azure ou à d’autres services), on obtient un code facilement testable. Les tests unitaires peuvent être écrits rapidement, avec des assertions claires sur les entrées/sorties du domaine.
Pour les tests d’intégration, chaque adaptateur peut être testé séparément : on vérifie qu’il remplit bien son contrat de port, sans impliquer l’ensemble de la chaîne. On limite ainsi les effets de bord et les erreurs systémiques.
Plutôt que de dépendre de vraies ressources Azure pour exécuter les tests, on peut injecter des adaptateurs factices (mocks, stubs ou fakes). Pour par exemple :
Ce contrôle permet de vérifier les comportements du domaine dans des cas limites, à moindre coût, sans environnement complexe.
Imaginons qu’un besoin métier émerge : diffuser les mêmes données vers une API partenaire en plus d’une base SQL. Dans une architecture classique, cela demande souvent une duplication de logique. En hexagonal, il suffit d’ajouter un adaptateur de sortie (Output Adapter) qui consomme les ports existants.
Cette souplesse permet une croissance incrémentale du système sans dette technique.
Azure Data Factory, Logic Apps et Synapse sont des outils puissants pour orchestrer des flux ETL ou d’automatisation. Mais ils ont tendance à embarquer la logique métier directement dans leurs définitions (UI ou JSON), ce qui contredit le principe de séparation propre à l’architecture hexagonale.
Cela dit, il est tout à fait possible de les utiliser de façon disciplinée : en les limitant à un rôle de « Port » ou d’orchestrateur, ils deviennent des points d’entrée ou de sortie qui délèguent la logique métier à des composants externes.
Par exemple, une Logic App peut agir comme un port entrant, en réceptionnant un webhook ou un message Service Bus, puis en appelant une Azure Function ou un conteneur qui contient la logique métier. Cela restera plus limité dans le cadre des Datafactory bien que le même principe soit imaginable.
Ils peuvent donc être utilisés pour appeler des adaptateurs ou orchestrer des composants hexagonaux, mais ne doivent pas contenir le domaine. Il faut donc les utiliser en tant qu’outils d’intégration de surface, pas comme moteur métier.
Azure Functions et leurs variantes (Durable Functions, WebJobs) sont parfaites pour appliquer les principes hexagonaux. On peut :
Cela permet de garder un code clair, testable, modulaire, tout en tirant profit des capacités serverless d’Azure.
Azure favorise les architectures découplées via des services comme Event Grid, Service Bus, ou Storage Queues. Ces mécanismes se marient très bien avec les adaptateurs hexagonaux :
Ainsi, l’infrastructure n’est plus une contrainte mais un facilitateur, intégré intelligemment dans un design propre.
Utiliser une architecture hexagonale pour de l’intégration de données dans Azure est non seulement possible, mais souhaitable, à condition que :
Pour des cas simples d’orchestration ETL, c’est probablement une complexité inutile. Mais dans des environnements distribués, data-centric, hybrides ou multi-cloud, cette architecture apporte la robustesse, la flexibilité et la pérennité qu’on attend d’une bonne solution d’intégration.