Après plusieurs projets implémentés avec l'architecture hexagonale (Ports & Adapters), voici un retour honnête sur ce que ça apporte réellement et les pièges à éviter.
L'architecture hexagonale — également connue sous le nom Ports & Adapters — a été formalisée par Alistair Cockburn en 2005. L'objectif est de séparer strictement le cœur métier de toute préoccupation technique : base de données, framework web, broker de messages, API tierce. Ces éléments d'infrastructure ne doivent jamais dicter la forme du domaine.
L'application est structurée en trois couches concentriques :
- Le domaine, au centre : entités, cas d'usage, règles métier — aucune dépendance vers l'extérieur.
- Les ports : des interfaces qui définissent les contrats d'entrée (ports entrants, déclenchés par les adaptateurs primaires) et de sortie (ports sortants, implémentés par les adaptateurs secondaires).
- Les adaptateurs : les implémentations concrètes branchées sur les ports — controllers REST, repositories JPA, clients d'API, brokers de messages, ou des tests automatisés.
La règle fondamentale : les dépendances ne pointent que vers le centre. Le domaine ne connaît jamais les adaptateurs. Changer de base de données, migrer vers un autre broker ou remplacer un client API n'impacte pas le code métier — seul l'adaptateur est modifié.
Cette approche est conceptuellement proche de la Clean Architecture de Martin, avec une terminologie différente. L'application est au centre, entourée de ports (interfaces définissant comment l'application communique avec l'extérieur) et d'adapters (implémentations concrètes : controllers REST, repositories JPA, clients d'API tierces). Les dépendances pointent toujours vers le centre.
En pratique sur un projet Spring Boot de taille moyenne, l'architecture hexagonale a transformé notre capacité à tester. Les use cases métier sont testés unitairement sans démarrer le contexte Spring, sans base de données, sans serveur HTTP. On injecte des mocks via les interfaces de port et on teste la logique pure. Le feedback loop est immédiat. Les tests d'intégration se concentrent sur les adapters — vérifier que le repository JPA fait bien ce que le port attend, que le controller REST sérialise correctement.
Les pièges identifiés : la sur-découpe en ports/adapters pour des opérations simples qui auraient pu rester dans un repository standard. Le mapping DTO ↔ Domaine ↔ Persistance multiplie les objets et le code de conversion — acceptable pour un domaine riche, pénible pour un CRUD. Notre recommandation : adoptez l'architecture hexagonale pour les bounded contexts à forte logique métier. Pour les parties CRUD d'un système, une architecture en couches classique (Controller → Service → Repository) est souvent suffisante et plus pragmatique.
→ À lire aussi : Clean Architecture · Domain-Driven Design · Les principes SOLID