Aller au contenu

Modéliser le contexte (C4)

Quatre niveaux de zoom pour communiquer l'architecture au bon public, avec le bon niveau de détail.


Pourquoi le modèle C4

Le modèle C4 de Simon Brown organisé la documentation d'architecture en quatre niveaux de zoom. Chaque niveau répond aux questions d'un public différent et élimine le détail inutile pour ce public. Le nom vient des quatre niveaux : Context, Container, Component, Code.

L'avantage du C4 par rapport à UML pur : chaque niveau a un public cible explicite. On ne produit pas un diagramme "pour documenter" — on produit un diagramme pour répondre a une question précisé d'un interlocuteur spécifique.

Un diagramme C4 n'est pas un exercice artistique. C'est un outil de communication. S'il ne répond pas a une question, il ne sert à rien. S'il répond à la mauvaise question pour le mauvais public, il crée de la confusion.


Les quatre niveaux

Niveau Public Quand l'utiliser
Level 1 — Context Toutes les parties prenantes Onboarding, kickoff, revue métier, sécurité
Level 2 — Container Équipe technique, ops Sprint planning, revue d'architecture, incident
Level 3 — Component Développeurs Design de feature, revue de code, onboarding dev
Level 4 — Code Développeurs Conception détaillée d'un composant complexe

Level 1 — Context

Vue la plus haute : le système dans son environnement. Qui l'utilisé ? Quels systèmes externes interagissent avec lui ? Ce diagramme est lisible par n'importe quelle partie prenante — métier, produit, sécurité, direction.

graph TD
    U[Utilisateur] -->|Passe commande via navigateur| APP[Application e-commerce]
    APP -->|Traite le paiement| PAY[Payment Provider\nStripe]
    APP -->|Envoie la confirmation| MAIL[Email Service\nSendGrid]
    APP -->|Exporte les commandes| ERP[ERP interne\nSAP]

Règle : pas de technologie dans ce diagramme. "Application e-commerce" pas "API Node.js sur Cloud Run". Le contexte répond a "qu'est-ce que le système fait et avec qui interagit-il ?", pas "comment est-il construit ?".

Bonnes pratiques Level 1

  • Inclure tous les acteurs humains et systèmes externes
  • Nommer les flux avec des verbes métier ("passe commande", "consulte le catalogue"), pas des protocoles ("HTTP GET", "POST /api/orders")
  • Limiter a 10-15 éléments maximum — au-delà, le diagramme perd sa lisibilite
  • Mettre à jour à chaque ajout d'intégration externe

Level 2 — Container

Decomposition du système en conteneurs deployables independamment : applications, bases de données, files de messages. Ce niveau répond a "sur quoi tourne l'application et comment les parties communiquent-elles ?"

graph TD
    U[Utilisateur] -->|HTTPS| SPA[SPA React\nVercel]
    SPA -->|REST / JSON| API[API Node.js\nCloud Run]
    API -->|SQL| DB[(PostgreSQL\nCloud SQL)]
    API -->|Publie evenements| MQ[Message Queue\nPub/Sub]
    MQ -->|Consomme| WORKER[Worker de notification\nCloud Run]
    WORKER -->|SMTP| MAIL[SendGrid]

À ce niveau, les technologies apparaissent. Chaque boite est un élément deployable séparément : une application web, un service backend, une base de données, une file de messages. Le terme "container" en C4 n'a rien a voir avec Docker — c'est un conteneur au sens "chose qui contient du code et qui est déployée".

Bonnes pratiques Level 2

  • Chaque conteneur doit pouvoir être déployé independamment
  • Indiquer le protocole de communication entre les conteneurs (REST, gRPC, SQL, AMQP)
  • Préciser la technologie et la plateforme de déploiement
  • Les bases de données sont des conteneurs — ne pas les oublier
  • Un conteneur = une responsabilité. Si un conteneur fait trop de choses, c'est un signe de decomposition nécessaire.

Level 3 — Component

Decomposition d'un conteneur en composants internes. Ce niveau répond a "comment ce conteneur est-il organisé en interne ?" Ici, l'intérieur de l'API Node.js :

graph TD
    subgraph "API Node.js"
        OC[OrderController] --> OS[OrderService]
        OS --> PS[PaymentService]
        OS --> NS[NotificationService]
        OS --> OR[OrderRepository]
    end
    OC -->|Requete HTTP| CLIENT[SPA React]
    PS -->|Stripe API| STRIPE[Stripe]
    NS -->|Publie evenement| MQ[Pub/Sub]
    OR -->|SQL| DB[(PostgreSQL)]

Ce niveau sert de base aux discussions de design de feature : quand on ajoute une nouvelle fonctionnalité, on identifié quel composant existant est impacte ou si un nouveau composant est nécessaire.

Bonnes pratiques Level 3

  • Ne decomposer que les conteneurs qui le necessitent — pas besoin d'un Level 3 pour une SPA simple
  • Un composant = une responsabilité technique claire (controller, service, repository, adapter)
  • Ce niveau guide la structure du code — si le diagramme et le code divergent, l'un des deux a tort
  • Limiter a 15-20 composants par conteneur. Au-delà, le conteneur devrait probablement être decompose

Level 4 — Code

Ce niveau correspond aux diagrammes de classes et sequences pour un composant spécifique — le niveau de détail utile lors de la conception d'un composant précis.

classDiagram
    class OrderService {
        -orderRepository: OrderRepository
        -paymentService: PaymentService
        -notificationService: NotificationService
        +createOrder(request: CreateOrderRequest): Order
        +cancelOrder(orderId: string): void
        +getOrder(orderId: string): Order
    }
    class OrderRepository {
        +save(order: Order): void
        +findById(id: string): Order
        +findByCustomer(customerId: string): Order[]
    }
    class Order {
        -id: string
        -customerId: string
        -items: OrderItem[]
        -status: OrderStatus
        -totalAmount: Money
        +addItem(item: OrderItem): void
        +calculateTotal(): Money
    }
    OrderService --> OrderRepository
    OrderService --> PaymentService
    OrderRepository --> Order

Le Level 4 est rarement maintenu

Le Level 4 se desynchronise rapidement avec le code. Il est utile pour la conception initiale d'un composant complexe, mais il ne doit pas être maintenu en permanence. Le code source est la vérité — le diagramme Level 4 est un support de réflexion temporaire. Pour les projets qui veulent un Level 4 à jour, utiliser des outils de génération automatique depuis le code.


Structurizr DSL

Structurizr est l'outil de référence pour les diagrammes C4. Son DSL (Domain Specific Language) permet de décrire l'architecture en texte et de générer les diagrammes automatiquement.

workspace {

    model {
        user = person "Utilisateur" "Passe des commandes via le navigateur"

        ecommerce = softwareSystem "Application e-commerce" {
            spa = container "SPA React" "Interface utilisateur" "React, TypeScript" "Web Browser"
            api = container "API Backend" "Logique metier et orchestration" "Node.js, Express"
            db = container "Base de donnees" "Stockage des commandes et utilisateurs" "PostgreSQL" "Database"
            queue = container "Message Queue" "Evenements asynchrones" "Google Pub/Sub" "Queue"
            worker = container "Worker de notification" "Traitement des notifications" "Node.js"
        }

        stripe = softwareSystem "Stripe" "Traitement des paiements" "External"
        sendgrid = softwareSystem "SendGrid" "Envoi d'emails" "External"

        user -> spa "Passe commande" "HTTPS"
        spa -> api "Appelle" "REST / JSON"
        api -> db "Lit et ecrit" "SQL"
        api -> queue "Publie evenements" "Pub/Sub"
        api -> stripe "Traite le paiement" "HTTPS"
        queue -> worker "Consomme" "Pull"
        worker -> sendgrid "Envoie email" "SMTP"
    }

    views {
        systemContext ecommerce "Context" {
            include *
            autoLayout
        }

        container ecommerce "Containers" {
            include *
            autoLayout
        }
    }

}

Avantages de Structurizr

  • Modèle unique, vues multiples : un seul fichier source généré les diagrammes de tous les niveaux
  • Versionnable : le DSL est du texte, il vit dans le dépôt Git avec le code
  • Cohérent : un élément renomme dans le modèle est renomme dans toutes les vues
  • Extensible : support des styles, des themes, des filtres par tag

Alternatives a Structurizr

Outil Type C4 natif Coût
Structurizr DSL + web Oui Gratuit (Lite)
PlantUML + C4 DSL Via lib Gratuit
Mermaid DSL embarque Markdown Partiel Gratuit
draw.io Visuel Via shapes Gratuit
Excalidraw Visuel Non Gratuit
Lucidchart Visuel Via shapes Payant

C4 vs UML vs ArchiMate

Les trois notations coexistent dans l'industrie. Chacune répond a un besoin différent.

Critère C4 UML ArchiMate
Public cible Toute l'équipe Développeurs Architectes enterprise
Courbe d'apprentissage Faible Moyenne a élevée Élevée
Formalisme Léger Fort (13 types de diagrammes) Fort (couches et relations)
Granularité 4 niveaux fixes Libre 3 couches (métier, app, tech)
Outillage Structurizr, Mermaid Enterprise Architect, PlantUML Archi, BiZZdesign
Standardisation Convention de fait Norme ISO/IEC 19501 Norme de l'Open Group

Quand choisir quoi

  • C4 : choix par défaut pour la documentation d'architecture d'un projet. Simple, lisible, suffisant dans 90% des cas.
  • UML : pour la modélisation détaillée du code (diagrammes de classes, sequences) — essentiellement Level 4.
  • ArchiMate : pour l'architecture enterprise quand on doit modéliser les couches métier, applicative et technique dans un cadre TOGAF.

Ne pas melanger les notations

Choisir une notation et s'y tenir pour un projet donne. Melanger C4 pour les conteneurs et UML pour les composants crée de la confusion. Si on a besoin de détail au niveau code, utiliser le Level 4 de C4 (qui peut emprunter la syntaxe UML pour les classes).


Quand s'arrêter

La question la plus courante avec C4 : "faut-il toujours aller jusqu'au Level 3 ou Level 4 ?"

Non. Le niveau de détail dépend du public et du besoin.

Situation Niveau suffisant
Présentation au sponsor Level 1
Onboarding d'un nouveau développeur Level 1 + 2
Sprint planning Level 2
Design d'une nouvelle feature Level 2 + 3
Conception d'un algorithme complexe Level 3 + 4
Audit de sécurité Level 1 + 2
Incident en production Level 2

Règle simple : s'arrêter au niveau ou la prochaine question trouve sa réponse dans le code, pas dans un diagramme.


Erreurs courantes

Erreur Conséquence Correction
Mettre des technologies au Level 1 Le diagramme contexte perd son public métier Garder les noms fonctionnels, pas techniques
Confondre container C4 et container Docker Le déploiement Docker n'est pas le container C4 Un container C4 = un deployable, pas un Dockerfile
Trop de boites au Level 2 Le diagramme devient illisible Limiter a 10-12 conteneurs, regrouper si besoin
Level 3 pour tous les conteneurs Sur-documentation sans valeur Level 3 uniquement pour les conteneurs complexes
Diagrammes jamais mis à jour Documentation mensongere Lier la mise à jour aux revues d'architecture
Pas de legende ni de contexte Le diagramme est ambiguite Ajouter un titre, une legende et une phrase de contexte
Fleches sans labels On ne sait pas ce qui circule Chaque fleche porte un verbe et/ou un protocole

Intégration avec les ADR

Les diagrammes C4 et les ADR se renforcent mutuellement :

  • Un ADR qui choisit une base de données → se reflete dans le diagramme Level 2
  • Un ADR qui decompose un service → crée un nouveau conteneur au Level 2 et un nouveau Level 3
  • Un changement dans le diagramme C4 sans ADR associe → décision implicite non documentee
graph LR
    ADR[ADR accepted] --"modifie"--> C4[Diagramme C4]
    C4 --"revele le besoin de"--> ADR2[Nouvel ADR]
    C4 --"communique a"--> PP[Parties prenantes]
    ADR --"justifie"--> C4

Maintenir ce lien garantit que les diagrammes ne sont pas des artefacts decoratifs mais des reflets des décisions prises.


Chapitre suivant : Trade-off analysis — rendre les compromis explicites pour que les décisions soient collectives, pas individuelles.