C4 Model
Le modèle C4 est une notation de diagrammes d’architecture logicielle proposée par Simon Brown vers 2011. Il répond à un problème que tout le monde a rencontré : les diagrammes d’architecture sont, en général, incompréhensibles.
Le symptôme est toujours le même. Des boîtes et des flèches, sans légende. Une boîte qui désigne une application à côté d’une boîte qui désigne une classe, et d’une troisième qui désigne un serveur. Des flèches dont personne ne sait si elles représentent un appel réseau, une dépendance de compilation ou un flux de données. Le diagramme est lisible par son auteur, pendant environ trois semaines.
UML avait résolu la question par la rigueur, et a échoué par le volume : personne ne l’utilise plus au quotidien. C4 fait le pari inverse — quatre abstractions et un principe de zoom, rien de plus.
Le vocabulaire avant les dessins
C’est le point le plus souvent manqué : C4 n’est pas d’abord une notation, c’est un jeu d’abstractions. La notation n’est qu’une conséquence, et elle est libre.
| Abstraction | Définition | Exemples |
|---|---|---|
| Personne | Un utilisateur humain, dans un rôle | Client, guichetier, administrateur |
| Système logiciel | La plus grande unité livrable, celle dont quelqu’un est responsable | La billetterie, le prestataire de paiement |
| Conteneur | Une unité exécutable ou déployable séparément, qui héberge du code ou des données | Une application web, une API, une base de données, un client mobile, une file de messages |
| Composant | Un regroupement de code derrière une interface, non déployable seul | Un contrôleur, un moteur de tarification, un adaptateur de paiement |
| Code | Classes, fonctions, structures | Reservation, CalculateurDeTarif |
Ces abstractions s’emboîtent : une personne utilise un système, un système contient des conteneurs, un conteneur contient des composants, un composant contient du code.
Warning
« Conteneur » ne signifie pas Docker. C’est la confusion la plus fréquente, et elle est antérieure à Docker : le terme désigne ce qui contient du code en cours d’exécution. Une base de données PostgreSQL est un conteneur C4, un bucket S3 aussi, et une application monopage dans un navigateur aussi — indépendamment de la façon dont tout cela est empaqueté ou déployé.
Les quatre niveaux
La métaphore de Brown est celle d’une carte : on part du monde, on zoome sur un pays, puis sur une ville, puis sur une rue. Chaque niveau de zoom montre une échelle, et une seule.
| Diagramme | Question | Public | À dessiner | |
|---|---|---|---|---|
| 1 | Contexte système | Qu’est-ce que ce système, qui l’utilise, à quoi parle-t-il ? | Tout le monde, y compris non technique | Toujours |
| 2 | Conteneurs | De quelles unités déployables est-il fait, avec quelles technologies ? | Équipes techniques, exploitation | Toujours — le plus utile des quatre |
| 3 | Composants | Comment un conteneur est-il organisé à l’intérieur ? | L’équipe qui développe ce conteneur | Sélectivement |
| 4 | Code | Quelles classes, quelles relations ? | Le développeur, sur le moment | Presque jamais |
Niveau 1 — Contexte système
Une boîte au centre : votre système. Autour : les personnes qui l’utilisent et les systèmes avec lesquels il échange. Aucun détail technique.
C’est le seul diagramme que l’on peut montrer à un directeur commercial, et il répond à une question rarement écrite noir sur blanc ailleurs : quelle est la frontière de notre responsabilité ?
Niveau 2 — Conteneurs
Le zoom à l’intérieur de la boîte centrale. Chaque conteneur porte son nom, sa technologie et son rôle ; chaque flèche porte le protocole.
C’est le diagramme qui rapporte le plus, et de loin. Il répond aux questions qu’on pose réellement en arrivant sur un projet : combien de choses à déployer, qu’est-ce qui parle à quoi, où sont les données, en quoi c’est écrit. Si vous n’en faites qu’un, faites celui-là.
Niveau 3 — Composants
Le zoom dans un conteneur. Utile, mais coûteux à maintenir — c’est le niveau qui change le plus souvent. À réserver aux conteneurs dont la structure interne n’est pas évidente : le cœur de métier, un conteneur particulièrement gros, ou celui que personne ne comprend.
Le tracer pour les huit conteneurs d’un système est presque toujours du travail perdu.
Niveau 4 — Code
Des diagrammes de classes. Simon Brown lui-même recommande de ne pas les maintenir : ils se périment à chaque commit, et n’importe quel IDE les génère à la demande avec plus de fiabilité. Ils ont un usage ponctuel — expliquer un motif de conception particulier — et rien à faire dans une documentation versionnée.
Ce qui rend un diagramme lisible
C4 ne prescrit aucune notation graphique. Il prescrit en revanche un contenu, et c’est ce qui fait la différence entre un diagramme utile et un schéma décoratif.
Chaque boîte porte quatre informations : un nom, son type — personne, système, conteneur, composant —, sa technologie quand elle en a une, et une description d’une ligne de ce qu’elle fait.
Chaque flèche porte une intention et un moyen : « lit et écrit les réservations », « JDBC ». Une flèche nue est une flèche inutile. Le sens indique qui initie, pas où vont les données.
Chaque diagramme a une légende. Toujours, même quand les conventions semblent évidentes.
Un diagramme, un niveau d’abstraction. C’est la règle la plus violée : dès qu’une classe apparaît à côté d’une application, le lecteur perd l’échelle et le diagramme ne veut plus rien dire.
Le diagramme se comprend sans son auteur. Le test réel : l’envoyer à quelqu’un sans commentaire, et voir s’il pose des questions.
Les diagrammes complémentaires
Trois types s’ajoutent aux quatre niveaux, et le dernier est très sous-utilisé.
Le paysage système (system landscape) élargit le niveau 1 à plusieurs systèmes : la vue d’ensemble d’une organisation, sans se limiter au périmètre d’une équipe.
Le diagramme dynamique montre un scénario : une séquence d’interactions numérotées, sur les éléments d’un niveau donné. C’est ce qu’on cherche quand on veut comprendre « comment se passe une réservation », question à laquelle un diagramme statique ne répond pas.
Le diagramme de déploiement projette les conteneurs sur l’infrastructure : quel conteneur tourne sur quel nœud, en combien d’instances, dans quel environnement. C’est là que se voient les points de défaillance uniques, et c’est régulièrement le diagramme le plus utile après le niveau 2 — souvent le seul document qui dise à quoi ressemble la production.
Les erreurs classiques
Mélanger les niveaux. Traité plus haut, et cité en premier parce que c’est le plus fréquent.
Confondre conteneur et Docker. Amène à ne pas représenter la base de données, qui est pourtant un conteneur, et à représenter des détails d’empaquetage qui n’en sont pas.
Dessiner le niveau 4. Beaucoup d’efforts, une obsolescence immédiate.
Vouloir un seul diagramme pour tout. Le réflexe de « la grande image d’architecture » produit une affiche que personne ne lit. Quatre diagrammes séparés, chacun tenant sur un écran, valent mieux qu’un schéma A0.
Documenter l’exhaustivité. Un diagramme est un outil de communication, pas un inventaire. Vingt-cinq conteneurs sur une vue rendent l’ensemble illisible : il faut alors plusieurs vues filtrées, ou reconnaître que le périmètre est trop large.
Le diagramme qui pourrit. Le plus coûteux à terme. Dessiné une fois dans un outil graphique, jamais mis à jour, il devient activement nuisible — un document faux fait perdre plus de temps qu’un document absent. C’est le problème que résout le passage au modèle décrit ci-dessous.
Sa place par rapport au reste
C4 décrit une structure. Il ne dit rien des raisons de cette structure, et rien des règles métier qu’elle sert. Trois compléments naturels :
- Les décisions — pourquoi PostgreSQL plutôt que MongoDB, pourquoi deux conteneurs plutôt qu’un — relèvent des ADR, dont Structurizr sait d’ailleurs rendre le contenu.
- Le découpage métier relève du Domain Driven Design. Un contexte délimité correspond souvent à un conteneur, ou à un groupe de composants dans un conteneur — mais la correspondance n’est pas une règle, et vouloir la forcer produit de mauvais diagrammes comme de mauvaises frontières.
- La structure interne d’un conteneur, si elle suit une architecture hexagonale, se lit très bien au niveau 3 : le domaine au centre, les adaptateurs autour.
C4 n’est pas non plus un remplaçant d’UML, mais un jeu d’abstractions plus léger. Rien n’interdit de le rendre en notation UML — c’est même explicitement prévu.
Le modèle plutôt que les diagrammes
Voici le glissement qui change tout, et le sujet de la sous-section suivante.
Un outil graphique produit n images indépendantes. Le niveau 1, le niveau 2 et le diagramme de déploiement contiennent tous le mot « API », trois fois, sans aucun lien entre eux. Quand l’API est renommée, il faut modifier trois fichiers, et l’on en oublie un. Les diagrammes ne divergent pas par négligence : ils divergent parce que rien ne les empêche de diverger.
L’alternative est de décrire un modèle — les éléments, leurs relations — puis d’en dériver autant de vues que nécessaire. Renommer l’API se fait à un seul endroit, et il devient structurellement impossible que deux diagrammes se contredisent.
C’est le principe de l’architecture-as-code, et l’outil de référence pour C4 est Structurizr, écrit par l’auteur du modèle.
- L’outil, son écosystème — DSL, CLI, Lite, Cloud — et la notion de workspace : un modèle, plusieurs vues.
- La syntaxe complète : modèle, éléments, relations, déploiement, identifiants, inclusions et modularité.
- Les types de vues, les expressions d’inclusion et d’exclusion, la mise en page automatique, les styles et les thèmes.
- Structurizr Lite en Docker, l’export via la CLI, la documentation et les ADR, l’intégration en CI — et les pièges.
Références
- https://c4model.com/ — la référence, par Simon Brown
- Simon Brown, Software Architecture for Developers, volume 2 — Visualise, document and explore your software architecture
- https://c4model.com/diagrams/notation — les conventions de notation recommandées
- https://www.youtube.com/watch?v=x2-rSnhpw0g — Visualising software architecture, la conférence de référence