Retour au blog

Architecture hexagonale exemple: 7 cas concrets 2026

21 juin 2026 · 23 min

Architecture hexagonale exemple: 7 cas concrets 2026

Votre code est-il un plat de spaghettis ? L'architecture hexagonale à la rescousse.

Trop d'applications finissent par devenir des monolithes pénibles à faire évoluer. Une petite modification sur une API HubSpot, Salesforce, Odoo ou Pennylane, et soudain la logique métier casse à un endroit qui n'avait rien demandé. Dans beaucoup de PME et d'ETI, le problème n'est pas seulement la dette technique. C'est le mélange permanent entre règles métier, contrôleurs HTTP, mapping JSON, accès base de données et scripts d'intégration.

L'architecture hexagonale, aussi appelée architecture à base de ports et d'adaptateurs, a été formalisée par Alistair Cockburn en 2005. Si elle reste d'actualité, c'est pour une raison simple. Elle a été conçue pour éviter les dépendances indésirables entre couches et la contamination du métier par l'interface utilisateur ou l'infrastructure. Le système s'organise autour d'un noyau métier, entouré de composants interchangeables reliés par des ports.

Pour une équipe qui doit industrialiser vite, l'intérêt est très concret. On peut tester le métier sans démarrer la base ou l'UI, remplacer un adaptateur CRM sans réécrire le cœur, et faire cohabiter plusieurs canaux d'entrée comme une API, un batch ou des tests automatisés. C'est particulièrement utile quand on ajoute des agents IA dans un SI déjà chargé.

Table des matières

1. Le concept originel d'Alistair Cockburn, le domaine bancaire

Lundi matin, un lot de virements part en erreur après un changement d'API côté prestataire. Dans beaucoup de SI, la règle métier de validation se retrouve mélangée au client HTTP, au mapping JSON et à la persistance. Le résultat est prévisible. Corriger un incident simple demande de toucher à plusieurs couches, avec un risque direct sur la production.

Le point de départ chez Cockburn est plus concret que la plupart des présentations théoriques ne le laissent penser. Il s'agit de garder le métier stable pendant que les points d'entrée et les dépendances externes bougent. Dans le bancaire, ce besoin saute aux yeux. Un virement, un contrôle de plafond, un rapprochement ou un refus de transaction doivent produire la même décision métier, que l'appel vienne d'un guichet, d'une API, d'un batch ou d'un outil interne.

La même logique vaut dans une PME qui branche un agent IA sur un CRM, un ERP et un outil de facturation. Si l'agent change, si le CRM migre, ou si l'ERP impose un nouveau protocole, le cœur métier ne doit pas être réécrit. C'est d'ailleurs le fil conducteur qu'on retrouve dans plusieurs retours d'expérience publiés sur le blog de Revolve sur l'industrialisation des agents IA et des intégrations SI.

Deux collègues discutent de l'architecture hexagonale autour d'un diagramme métier imprimé dans un bureau moderne.

Le schéma minimal qui tient en production

Sur le terrain, je conseille un découpage simple. Pas un hexagone académique avec dix couches. Un noyau métier, des cas d'usage, puis des ports bien nommés.

  • Ports primaires : ce qui déclenche l'action métier. API REST, webhook CRM, tâche planifiée, import batch, commande lancée par un agent IA.
  • Ports secondaires : ce que le métier appelle. PSP, ERP, CRM, service de facturation, email, GED.
  • Règle de base : le domaine dépend d'interfaces métier, jamais d'un SDK fournisseur, d'un client HTTP concret ou d'un ORM.

Règle pratique
Si votre use case mentionne une URL, un token, un repository JPA ou un objet de payload externe, il est déjà trop bas dans la pile.

Ce découpage a un coût. Il faut écrire des interfaces, des adaptateurs et parfois des tests supplémentaires. Dans une petite application CRUD, ce coût n'est pas toujours justifié. En revanche, dès qu'un même cas d'usage doit survivre à plusieurs canaux d'entrée et à plusieurs outils tiers, l'investissement est vite rentabilisé. L'équipe change un connecteur sans risquer la règle de validation métier. Elle teste un refus de paiement ou un dépassement de plafond sans démarrer la base ni le fournisseur externe.

L'intérêt n'est donc pas seulement architectural. Il est opérationnel. Une équipe qui doit livrer vite, maintenir peu de code et intégrer progressivement de nouveaux outils garde une zone stable au centre du système, pendant que la périphérie évolue.

Exemple de code côté domaine

public interface PaymentPort {
    PaymentResult charge(Money amount, CustomerId customerId);
}

public interface InvoicePort {
    void createInvoice(OrderId orderId, Money amount);
}

public final class ConfirmPaymentUseCase {
    private final PaymentPort paymentPort;
    private final InvoicePort invoicePort;

    public ConfirmPaymentUseCase(PaymentPort paymentPort, InvoicePort invoicePort) {
        this.paymentPort = paymentPort;
        this.invoicePort = invoicePort;
    }

    public void handle(Order order) {
        PaymentResult result = paymentPort.charge(order.total(), order.customerId());
        if (!result.isAccepted()) {
            throw new BusinessException("Paiement refusé");
        }
        invoicePort.createInvoice(order.id(), order.total());
    }
}

Ce code reste volontairement austère. C'est un bon signe. Le cas d'usage exprime une décision métier lisible, testable et indépendante des outils. Le vrai travail d'industrialisation arrive autour. Nommer les ports selon le langage métier, isoler les DTO d'intégration dans les adaptateurs, gérer les erreurs techniques sans les faire remonter telles quelles au domaine, et poser une structure de dossiers que l'équipe respecte vraiment. C'est souvent là que la version "exemple de blog" devient une architecture qui tient six mois après la mise en production.

Comme l'explique aussi Scalastic dans sa présentation de l'architecture hexagonale, l'inversion des dépendances protège le noyau métier des détails techniques. Dans un contexte bancaire comme dans une PME qui connecte CRM, ERP et automatisations IA, c'est ce qui évite que chaque nouvelle intégration finisse par redessiner toute l'application.

2. DDD et Ports Adapters, l'orchestration e-commerce

Là où l'architecture hexagonale devient vraiment intéressante, c'est quand le métier a des invariants. En e-commerce, une commande n'est pas juste une ligne en base. Il y a des règles de disponibilité, de paiement, de livraison, de remise, d'annulation et parfois de validation manuelle.

Si vous combinez DDD et ports/adapters, vous obtenez quelque chose de très exploitable. Le domaine porte les concepts. Les cas d'usage orchestrent. Les adaptateurs branchent Stripe, Shopify, HubSpot, Odoo, un moteur d'emailing ou un outil maison.

Quand le domaine mérite vraiment un hexagone

Toutes les applications n'en ont pas besoin. C'est un point souvent passé sous silence. Certaines sources rappellent qu'il faut un vrai noyau métier à protéger, sinon la surcharge de ports, adaptateurs et DTO peut ajouter de la complexité sans bénéfice clair dans cet article Ouidou sur l'architecture hexagonale en .NET.

Pour un orchestrateur e-commerce, les critères sont assez simples :

  • Métier riche : calcul de remise, conditions de livraison, règles de stock, arbitrage entre plusieurs moyens de paiement.
  • Intégrations mouvantes : changement de PSP, ajout d'un ERP, migration d'un CRM, refonte du front.
  • Tests métier nécessaires : vous voulez valider un flux de commande sans démarrer la base, l'UI ou les services tiers.

Si votre application ne fait qu'exposer un CRUD sur trois tables, restez simple. L'hexagone est utile quand il protège quelque chose qui vaut la peine d'être isolé.

Une structure de dossiers utile

Une structure qui fonctionne bien en PME ressemble à ça :

src/
  domain/
    order/
      Order.ts
      OrderLine.ts
      OrderRepository.ts
    customer/
      Customer.ts
    shared/
      Money.ts
  application/
    usecases/
      PlaceOrder.ts
      CancelOrder.ts
      GenerateQuote.ts
    dto/
      PlaceOrderCommand.ts
  adapters/
    inbound/
      http/
        OrderController.ts
      messaging/
        LeadQualifiedHandler.ts
    outbound/
      crm/
        HubSpotContactAdapter.ts
      erp/
        OdooOrderAdapter.ts
      payment/
        StripePaymentAdapter.ts
      persistence/
        PostgresOrderRepository.ts

Ce découpage force de bonnes décisions. Un use case comme GenerateQuote parle métier. L'adaptateur HubSpotContactAdapter ne contient que la traduction entre le langage externe et le langage du domaine. Quand un agent commercial automatise la qualification d'un lead, puis déclenche la création d'un devis, vous avez une place claire pour chaque responsabilité.

Dans ce modèle, les événements métier aident beaucoup. LeadQualified, QuoteGenerated ou OrderConfirmed permettent de brancher des adaptateurs sans coller l'orchestration à la logique de cœur. C'est souvent la frontière qui manque dans les projets qui grandissent trop vite.

3. Spring Boot et Clean Architecture, le microservice multi-intégrations

Beaucoup d'équipes Java arrivent à l'architecture hexagonale après une phase douloureuse. Le contrôleur Spring appelle un service applicatif, qui appelle un repository, qui appelle une API externe au passage, et personne ne sait plus où vivent les règles métier. Le projet compile. Il ne respire plus.

Avec Spring Boot, l'erreur classique consiste à laisser le framework dicter tout le design. Il faut faire l'inverse. Le domaine et les cas d'usage d'abord. Spring ensuite.

Une base de projet qui évite le chaos

Les recommandations françaises sur le sujet insistent sur l'indépendance du noyau métier, avec des dépendances qui pointent vers la logique métier et des interactions qui passent par ports et adaptateurs. Elles mentionnent aussi une structuration séparée de type entrypoints, domain et adapters dans l'exemple OCTO.

En pratique, pour un microservice de qualification de leads ou de synchronisation CRM, je pars souvent sur ceci :

src/main/java/com/acme/leads/
  domain/
    model/
    port/
    service/
  application/
    usecase/
    command/
    result/
  adapters/
    inbound/
      rest/
      batch/
    outbound/
      crm/
      billing/
      persistence/
  configuration/

Cette séparation évite que @RestController, JpaRepository ou un client HTTP se faufilent partout. Votre code de domaine reste compilable et testable sans lancer Spring.

Exemple Java sur un port CRM

public interface CrmPort {
    void upsertLead(Lead lead);
}

public final class QualifyLeadUseCase {
    private final CrmPort crmPort;
    private final LeadScoringService scoringService;

    public QualifyLeadUseCase(CrmPort crmPort, LeadScoringService scoringService) {
        this.crmPort = crmPort;
        this.scoringService = scoringService;
    }

    public QualificationResult handle(QualifyLeadCommand command) {
        Lead lead = Lead.from(command.email(), command.companyName(), command.source());
        Score score = scoringService.score(lead);
        Lead qualified = lead.qualify(score);
        crmPort.upsertLead(qualified);
        return new QualificationResult(qualified.id(), score.value());
    }
}

Le point important n'est pas le framework. C'est la direction des dépendances. Le domaine ne connaît pas HubSpot ni Salesforce. L'adaptateur, lui, connaît les détails d'API, les retries, les timeouts et les mappings.

  • Configuration Spring : utilisez des @Configuration pour instancier les bons adaptateurs selon l'environnement.
  • Résilience : mettez les protections réseau dans l'adaptateur, pas dans le domaine.
  • Tests : testez QualifyLeadUseCase avec un faux CrmPort, sans contexte Spring.

Pour un microservice multi-intégrations, cette discipline paie vite. Les changements d'API externe restent cantonnés à la périphérie. Le cœur, lui, continue à tourner.

4. Node.js TypeScript, la synchronisation CRM temps réel

Node.js est très bon quand il faut connecter des événements externes, traiter des webhooks et enchaîner des synchronisations rapides. C'est encore plus vrai si vous imposez TypeScript strict dès le départ. Sans ça, beaucoup de projets de sync CRM deviennent des usines à any.

L'usage le plus fréquent en PME, c'est le pont entre plusieurs outils qui n'emploient pas le même vocabulaire. Un lead arrive de HubSpot, enrichi par un service tiers, recopié dans Salesforce, puis consolidé dans Odoo. Le domaine doit décider ce qu'est un lead qualifié. Les adaptateurs traduisent les formats.

Une équipe de professionnels collabore devant un ordinateur portable affichant des données de synchronisation en temps réel.

Là où Node.js brille vraiment

Je trouve cette stack particulièrement adaptée quand les entrées sont nombreuses et imprévisibles. Webhooks, queues, tâches planifiées, API publiques, événements d'emailing. L'hexagone permet alors d'éviter deux dérives fréquentes : mettre la logique métier dans les handlers HTTP, ou distribuer la logique de mapping dans tout le code.

Une bonne règle consiste à faire des handlers très minces. Ils valident, traduisent, délèguent. Le cas d'usage décide. L'adaptateur sortant écrit dans le bon CRM, avec la bonne stratégie.

Un webhook ne devrait jamais contenir la règle de qualification d'un lead. Il devrait seulement convertir un payload externe en commande métier.

Exemple TypeScript pour un webhook entrant

export interface CrmSyncPort {
  upsertContact(contact: QualifiedLead): Promise<void>;
}

export class ProcessHubSpotWebhook {
  constructor(private readonly crmSyncPort: CrmSyncPort) {}

  async execute(input: HubSpotWebhookCommand): Promise<void> {
    const lead = QualifiedLead.fromInboundData(
      input.email,
      input.company,
      input.lifecycleStage
    );

    if (!lead.isSyncable()) {
      return;
    }

    await this.crmSyncPort.upsertContact(lead);
  }
}

Côté structure, j'aime bien :

src/
  domain/
  application/
  adapters/
    inbound/http/
    inbound/queue/
    outbound/hubspot/
    outbound/salesforce/
    outbound/odoo/
  shared/

Et côté production :

  • Secrets : variables d'environnement ou coffre dédié.
  • Logs : JSON structuré avec identifiant de corrélation.
  • Asynchrone : Bull ou RabbitMQ pour découpler réception et exécution.
  • Tests : Jest sur le domaine, tests d'intégration ciblés sur les adaptateurs.

Le gain est surtout organisationnel. Chaque intégration externe reste remplaçable. Votre service de synchronisation ne devient pas prisonnier du premier CRM branché.

5. Python FastAPI, l'agent d'automatisation et son orchestration

Dès qu'on parle d'agents IA, Python revient souvent pour de bonnes raisons. FastAPI permet d'exposer vite une API propre, Pydantic aide à verrouiller les échanges, et l'écosystème Python reste pratique pour brancher des modèles, des parseurs PDF ou des pipelines d'enrichissement.

Le piège, là aussi, c'est de laisser l'orchestration contaminer tout le code. Un agent qui lit un email, extrait des données, décide d'une action, interroge un CRM et crée une facture peut devenir ingérable très vite si tout vit dans une seule fonction async.

Un développeur travaillant sur un ordinateur portable, se concentrant sur l'orchestration d'agents dans un environnement de bureau.

Un bon fit pour les agents IA branchés au SI

La valeur opérationnelle la plus forte de l'architecture hexagonale reste la testabilité du domaine. Les sources françaises le rappellent bien : si les règles métier restent dans le noyau et que les dépendances externes passent par des interfaces, on peut tester les cas d'usage sans démarrer base de données, UI ou services tiers dans cette mise en pratique Sciam.

C'est exactement ce qu'il faut pour un agent d'automatisation. Le comportement métier doit être testable sans appeler un LLM, sans parler à HubSpot, sans pousser un document dans Pennylane. Le domaine décide qu'un devis est éligible, qu'une facture doit être envoyée ou qu'un lead doit être rejeté. Les adaptateurs exécutent.

Exemple Python avec ports et adaptateurs

from pydantic import BaseModel
from typing import Protocol

class CreateInvoiceCommand(BaseModel):
    customer_id: str
    amount: float
    source: str

class BillingPort(Protocol):
    async def create_invoice(self, customer_id: str, amount: float) -> str:
        ...

class CreateInvoiceUseCase:
    def __init__(self, billing_port: BillingPort):
        self.billing_port = billing_port

    async def execute(self, cmd: CreateInvoiceCommand) -> str:
        if cmd.amount <= 0:
            raise ValueError("Montant invalide")
        return await self.billing_port.create_invoice(cmd.customer_id, cmd.amount)

Une structure réaliste :

app/
  domain/
    lead.py
    quote.py
    invoice.py
  application/
    use_cases/
    commands/
  adapters/
    inbound/
      api/
      jobs/
    outbound/
      crm/
      accounting/
      llm/
  bootstrap/

Pour des flux administratifs, l'exemple de l'automatisation des factures chez Revolve illustre bien le besoin. L'agent ne doit pas confondre logique de validation métier et code d'intégration comptable.

  • DTO Pydantic : pour tous les échanges entrants et sortants.
  • Retry et backoff : dans les adaptateurs API fragiles.
  • Injection de dépendances : légère, lisible, sans magie excessive.
  • LLM : traité comme une dépendance externe, jamais comme le domaine.

6. C# .NET, l'intégration ERP d'entreprise

Lundi matin, un achat validé dans le portail interne doit partir dans l'ERP, déclencher un contrôle budgétaire, puis alimenter un reporting finance. Le flux semble simple jusqu'au jour où un import CSV, une reprise manuelle et une API interne écrivent chacun une variante différente de la même commande. C'est souvent là que les équipes découvrent que le vrai sujet n'est pas .NET. C'est la frontière entre le métier et les intégrations.

Dans les PME et ETI, .NET reste un choix fréquent dès qu'on touche à l'ERP, aux workflows internes, à l'Active Directory, à la comptabilité ou à des applications historiques. Le piège classique consiste à laisser les modèles SAP, Sage, Cegid ou Odoo remonter dans les services applicatifs, puis dans le domaine. Au bout de quelques itérations, chaque évolution métier impose de relire des mappings, des DTO ERP et des helpers techniques qui n'ont rien à faire au centre.

L'architecture hexagonale corrige ce problème si elle reste sobre. En pratique, j'associe souvent un cœur métier simple, quelques ports explicites et un CQRS léger. Pas pour suivre un dogme. Pour isoler les commandes qui modifient l'état des lectures destinées au back-office, aux exports ou aux écrans de contrôle.

Pourquoi .NET fonctionne bien sur une intégration ERP

Le principal intérêt n'est pas théorique. Il tient à la capacité de faire cohabiter plusieurs points d'entrée sans dupliquer les règles. Une API interne, un job planifié, un import Excel ou CSV, parfois un message issu d'un bus. Tous appellent le même cas d'usage. Les adaptateurs traduisent. Le domaine décide.

C'est aussi une bonne base pour cadrer un POC avant industrialisation. Sur un POC en PME bien cadré, je recommande de valider d'abord trois choses : le contrat du port ERP, la gestion des erreurs métier et la reprise sur incident. Si ces points restent flous au prototype, la mise en production coûtera plus cher que le développement initial.

Exemple CQRS simple dans un hexagone

public record CreateSupplierOrderCommand(string SupplierId, decimal Amount);

public interface ISupplierOrderRepository
{
    Task SaveAsync(SupplierOrder order);
}

public class CreateSupplierOrderHandler
{
    private readonly ISupplierOrderRepository _repository;

    public CreateSupplierOrderHandler(ISupplierOrderRepository repository)
    {
        _repository = repository;
    }

    public async Task Handle(CreateSupplierOrderCommand command)
    {
        var order = SupplierOrder.Create(command.SupplierId, command.Amount);
        await _repository.SaveAsync(order);
    }
}

Le point important n'est pas le handler lui-même. C'est ce qu'il ne sait pas. Il ne connaît ni l'API ERP, ni le format d'un fichier d'import, ni la manière dont un agent IA propose une commande à créer. Il exécute une intention métier et délègue la persistance à un port.

Une structure de dossiers réaliste en .NET ressemble souvent à ceci :

src/
  Domain/
    SupplierOrders/
    Budgeting/
    Accounting/
  Application/
    Commands/
    Queries/
    UseCases/
    Ports/
  Adapters/
    Inbound/
      Api/
      Jobs/
      CsvImport/
    Outbound/
      Erp/
      Messaging/
      DocumentGeneration/
  Infrastructure/
    Persistence/
    DependencyInjection/
tests/
  Domain.Tests/
  Application.Tests/
  IntegrationTests/

Cette séparation aide sur un cas très concret. Une commande fournisseur peut venir d'un acheteur, d'un batch de régularisation ou d'un agent IA branché sur un CRM ou un ERP existant. Le même use case applique les validations métier. Chaque canal garde son adaptateur. On évite ainsi le contrôleur API qui devient le point d'entrée officieux de toute la logique de l'entreprise.

Quelques choix techniques tiennent bien la route en production :

  • MediatR : utile si l'équipe veut un point de passage clair pour commandes et requêtes. Inutile si cela masque le flux d'exécution.
  • Un adaptateur par grande intégration : ERP, GED, messagerie, génération documentaire. Évitez le connecteur unique qui finit par concentrer toutes les exceptions du SI.
  • Tests ciblés : xUnit sur le domaine et les handlers. Mocks limités aux ports. Les tests d'intégration doivent couvrir les mappings ERP qui cassent le plus souvent.
  • Idempotence : indispensable dès qu'un batch, une queue ou une reprise manuelle peut rejouer une même commande.
  • Journalisation métier : loggez les identifiants fonctionnels, pas seulement les erreurs techniques. Sinon, le support ne retrouve pas un flux bloqué.

Le compromis est connu. Cette discipline ajoute un peu de structure au départ. En échange, les évolutions restent localisées. Sur des flux d'achats, de comptabilité ou de rapprochement ERP, c'est souvent le bon arbitrage pour livrer vite sans transformer chaque correction en opération à risque.

7. Avec Event Sourcing, la coordination d'agents multi-canaux

Quand plusieurs agents ou services interviennent sur le même processus, le problème n'est plus seulement l'architecture. C'est la traçabilité. Qui a qualifié le lead ? Quand le devis a-t-il été généré ? Pourquoi la synchronisation CRM a-t-elle divergé de l'ERP ? Quel événement faut-il rejouer après correction ?

L'Event Sourcing répond bien à ce besoin, à condition de ne pas l'employer partout. Sur un flux métier critique, il permet d'enregistrer les événements métier immuables et de reconstruire l'état à partir d'eux. Couplé à un hexagone, il garde un centre propre et des projections spécialisées à l'extérieur.

Quand l'historique métier devient un actif

Je le recommande sur des processus où l'audit compte vraiment. Qualification de leads, génération de devis, décisions prises par un agent, synchronisations entre systèmes, validation de documents. Dans ce contexte, l'historique n'est pas un log technique. C'est une preuve métier.

En revanche, pour une simple application CRUD, c'est souvent trop lourd. L'hexagone peut suffire sans Event Sourcing. Là encore, il faut choisir selon la nature du domaine et non par mimétisme.

"Commencez par capturer des événements métier utiles. Pas tous les détails techniques."

Exemple d'événements métier utiles

LeadCaptured
LeadQualified
QuoteGenerated
QuoteSent
CrmContactUpserted
InvoiceRequested
InvoiceCreated
SignatureCompleted

Chaque événement doit être petit, immuable et compréhensible par le métier. LeadProcessed est trop flou. LeadQualified et QuoteGenerated sont beaucoup plus exploitables.

Pour démarrer sans vous noyer :

  • Store simple : un stockage événementiel minimal peut suffire au départ.
  • Projections ciblées : une vue CRM, une vue comptable, une vue analytique.
  • Snapshots : utiles quand certains agrégats accumulent un long historique.
  • Saga : pertinente si plusieurs services doivent coordonner un même parcours.

Dans un contexte d'agents IA, cette approche aide aussi à distinguer ce qu'a décidé le domaine de ce qu'a exécuté l'infrastructure. C'est précieux quand vous passez d'un POC à un produit durable. Le sujet est très proche de la différence entre expérimentation et industrialisation évoquée dans cet article Revolve sur ce qu'est un POC.

Comparatif : 7 exemples darchitecture hexagonale

Solution 🔄 Complexité d'implémentation ⚡ Ressources & rapidité ⭐ Résultats attendus 📊 Cas d'usage idéal 💡 Avantages clés
Le concept originel d'Alistair Cockburn : le domaine bancaire Moyenne→Élevée : modélisation métier et découplage requis Modéré : temps d'architecture, coût moyen de développement Cœur métier isolé, testabilité maximale, intégrations interchangeables Orchestration agents IA multi‑CRM, migrations CRM Séparation nette domaine/adaptateurs, facilite tests et migrations
DDD & Ports/Adapters : l'orchestration e‑commerce Élevée : overhead DDD et modélisation fine Élevé : besoins d'experts, cycles de conception plus longs Clarté métier, forte évolutivité, découplage via événements Plateformes e‑commerce complexes, CRM+compta multi‑domaines Code aligné avec le business, events pour découplage asynchrone
Spring Boot & Clean Architecture : microservice multi‑intégrations Moyenne : configuration Spring et structure en couches Moyenne→Élevée : dépendances Java/Spring, déploiement Kubernetes Solution robuste, maintenable et scalable en production Microservices d'intégration CRM/ERP en production Écosystème mature, DI solide, tests et déploiement industrialisés
Node.js/TypeScript : synchronisation CRM temps réel Faible→Moyenne : approche légère, patterns JS simples Faible : déploiement rapide (2–8 sem), faible footprint cloud Latence faible, synchronisation en temps réel, coût réduit Webhooks, sync HubSpot↔Salesforce, agents temps‑réel Développement rapide, typage TypeScript, excellent pour webhooks
Python/FastAPI : agent d'automatisation et orchestration Moyenne : async, DI et orchestration de workflows Modéré : performant pour IA/ML, déploiement rapide sur Cloud Run Orchestration d'agents IA efficace, intégration LLM fluide Pipelines IA, enrichment de leads, orchestration LLMs Pydantic pour validation, async natif, riche écosystème ML
C#/.NET : intégration ERP d'entreprise Moyenne→Élevée : CQRS, MediatR et patterns enterprise Élevé : outillage Microsoft, ressources serveur, coûts possibles Très robuste et performant pour workloads lourds Intégration SAP/Cegid/Odoo, processus financiers critiques Typage fort, CQRS naturel, outillage Visual Studio professionnel
Avec Event Sourcing : coordination d'agents multi‑canaux Très élevée : ES + CQRS + Sagas, forte complexité Très élevé : Event Store/Kafka, infrastructure et coût importants Auditabilité complète, replay, traçabilité et conformité Clients audités (finance, construction), besoins de replay Historique immuable, diagnostics par replay, conformité renforcée

Passer à l'action, industrialiser l'architecture hexagonale dans votre PME

L'architecture hexagonale n'est pas réservée aux grands groupes ni aux équipes qui ont le luxe de refaire leur stack pendant des mois. Elle est surtout utile quand votre métier vaut plus que vos intégrations. C'est le cas de beaucoup de PME et d'ETI françaises qui doivent faire cohabiter CRM, ERP, messagerie, reporting et automatisations IA sans transformer leur SI en patchwork fragile.

Le bon point de départ n'est pas une refonte générale. C'est un service précis, avec un périmètre clair et un domaine identifiable. Par exemple, la qualification d'un lead, la génération d'un devis, l'extraction de données depuis un PDF ou la synchronisation d'une commande vers un ERP. Vous isolez un cas d'usage, vous posez vos ports, puis vous branchez les adaptateurs autour. C'est beaucoup plus réaliste qu'un grand chantier de réarchitecture.

L'autre bonne décision consiste à accepter les compromis. Tout ne mérite pas un hexagone complet. Si vous avez un petit back-office CRUD sans règles métier fortes, restez simple. Si vous avez un processus qui concentre du risque, de la variabilité métier et plusieurs dépendances externes, l'architecture hexagonale devient rentable. C'est là qu'elle apporte de la maintenabilité, de la testabilité et une meilleure tenue en production.

Dans la pratique, j'encourage les équipes à suivre quatre règles. Premièrement, gardez le domaine pur. Aucun SDK, aucun ORM, aucune logique d'authentification externe dans les cas d'usage métier. Deuxièmement, acceptez les DTO et les mappers à la frontière. Ils paraissent verbeux, mais ils évitent que les modèles externes contaminent votre cœur applicatif. Troisièmement, testez le domaine sans framework. Si un use case exige de lancer Spring, FastAPI ou ASP.NET pour être validé, le découplage n'est pas assez fort. Quatrièmement, industrialisez les adaptateurs comme des composants jetables. Ils doivent pouvoir être remplacés quand un outil change.

L'intérêt devient encore plus net quand vous ajoutez des agents IA. Un agent n'est pas seulement un appel à un modèle. C'est un composant qui prend des décisions dans un flux métier réel, avec des entrées ambiguës et des sorties qui ont des conséquences sur vos données, vos devis, vos factures ou vos relances commerciales. Sans séparation stricte entre domaine et infrastructure, ces agents finissent vite par disperser des règles métier dans des prompts, des scripts ou des handlers impossibles à auditer.

C'est précisément pour ça que cette approche fonctionne bien en PME et ETI. Elle permet de livrer vite sans sacrifier l'avenir. Vous pouvez démarrer petit, brancher les premiers outils, sécuriser les tests, puis étendre le périmètre sans réécrire le socle à chaque nouvelle intégration. L'architecture hexagonale n'est pas un but. C'est une discipline de découplage. Bien appliquée, elle rend vos automatisations plus fiables et vos équipes plus sereines.


Si vous voulez industrialiser des agents IA réellement branchés à votre CRM, votre ERP ou vos flux administratifs, Revolve peut vous aider à cadrer le bon périmètre, concevoir une architecture propre et livrer rapidement une première mise en production utile. Leur approche est particulièrement pertinente si vous voulez dépasser le POC et construire un système maintenable, testable et intégré à vos outils existants.

Architecture hexagonale exemple: 7 cas concrets 2026 | Blog Revolve AI