Le principe
Introduite par Alistair Cockburn en 2005, l'architecture hexagonale repose sur une idée simple : le domaine métier ne doit dépendre de rien — ni de la base de données, ni du framework web, ni d'un service externe.
Toutes les interactions avec l'extérieur passent par des ports (interfaces définies par le domaine) et des adaptateurs (implémentations concrètes fournies par l'infrastructure).
Adaptateur entrant
Adaptateur entrant
Adaptateur entrant
Adaptateur sortant
Adaptateur sortant
Adaptateur sortant
Ports & Adapters en détail
Les Ports
Un port est une interface définie par le domaine. Il représente un besoin du domaine sans savoir comment il sera satisfait. Il en existe deux types :
Ce que le domaine expose au monde extérieur. Ce sont les use cases : les actions que l'utilisateur ou un système peut déclencher.
Ce dont le domaine a besoin depuis l'extérieur. Exemple : CommandeRepository, EmailSender, StockService.
Les Adaptateurs
Un adaptateur est l'implémentation concrète d'un port. Il fait le lien entre le domaine et le monde extérieur (framework, base de données, API tierce).
// PORT SORTANT – défini par le domaine public interface CommandeRepository { Commande findById(CommandeId id); void save(Commande commande); } // ADAPTATEUR – implémentation infrastructure (JPA) public class JpaCommandeRepository implements CommandeRepository { private final JpaCommandeJpaRepository jpaRepo; public Commande findById(CommandeId id) { return jpaRepo.findById(id.value()) .map(CommandeMapper::toDomain) .orElseThrow(); } }
Structure de projet type
src/main/java/ ├── domain/ ← cœur métier, 0 dépendance externe │ ├── model/ ← entités, agrégats, value objects │ ├── port/ │ │ ├── in/ ← interfaces use cases (ports entrants) │ │ └── out/ ← interfaces repo/services (ports sortants) │ └── service/ ← logique métier (implémente les ports entrants) │ ├── application/ ← orchestration, DTOs, mappers │ └── infrastructure/ ← adaptateurs concrets ├── web/ ← controllers REST (adaptateur entrant) ├── persistence/ ← JPA, repositories (adaptateur sortant) └── messaging/ ← RabbitMQ, Kafka (adaptateur sortant)
Avantages
- Testabilité : le domaine peut être testé sans base de données ni framework, avec de simples mocks des ports sortants
- Flexibilité : changer de base de données ou de framework ne touche pas au domaine
- Lisibilité : le code métier est clairement séparé du code technique
- Compatibilité DDD : s'intègre naturellement avec les principes du Domain-Driven Design
Frameworks Java
Spring Boot Quarkus Micronaut jMolecules ArchUnit (tests d'architecture)