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.