Retour au portfolio Culture technique
Architecture logicielle

Architecture Hexagonale

Aussi appelée Ports & Adapters, cette architecture isole le cœur métier de l'application de toute dépendance technique, pour un code plus testable et plus évolutif.

Ports & Adapters Clean Architecture Testabilité Découplage

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).

Vue d'ensemble – Ports & Adapters
API REST
Adaptateur entrant
CLI
Adaptateur entrant
Tests
Adaptateur entrant
↕ Ports entrants (Use Cases)
⭐ Domaine métier
Entités · Agrégats · Services
↕ Ports sortants (Repositories, etc.)
PostgreSQL
Adaptateur sortant
RabbitMQ
Adaptateur sortant
API externe
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 :

Ports entrants (Driving)

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.

Ports sortants (Driven)

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

Règle d'or : les dépendances pointent toujours vers le domaine, jamais depuis le domaine vers l'extérieur. Le domaine ne connaît ni Spring, ni JPA, ni PostgreSQL.

Frameworks Java

Spring Boot Quarkus Micronaut jMolecules ArchUnit (tests d'architecture)