Diagramme de composants C4 : guide complet avec exemples
Le diagramme de composants est le niveau 3 du modèle C4 -- et c'est le niveau qui a la pire réputation. Le niveau 1 (Contexte Système) est facile à dessiner et change rarement. Le niveau 2 (Container) correspond directement à ce que vous déployez. Mais le niveau 3 ? Il zoome dans les entrailles d'un seul container, ce qui signifie qu'il change chaque fois qu'un développeur restructure un package. La plupart des équipes le sautent complètement, ou le dessinent une fois et le laissent pourrir.
C'est dommage, parce qu'un diagramme de composants bien maintenu est l'artefact le plus utile pour un développeur qui rejoint une codebase. Il répond à la question que tout nouvel arrivant se pose : "où vit réellement la logique de X ?"
Ce guide couvre ce qu'est un diagramme de composants C4, en quoi il diffère du diagramme de composants UML, quand le niveau 3 vaut son coût de maintenance (et quand il ne le vaut pas), un exemple complet, les erreurs qui rendent les diagrammes de composants inutiles, et comment les garder exacts sans tout faire à la main.
Si vous découvrez le modèle C4, commencez par notre guide complet du modèle C4, puis revenez ici.
Qu'est-ce qu'un diagramme de composants C4 ?
Un diagramme de composants ouvre un seul container -- une unité déployable de votre diagramme de containers -- et révèle les composants qu'il contient.
Dans la terminologie C4, un composant est un regroupement cohésif de fonctionnalités liées, derrière une interface bien définie. Pensez aux blocs de construction majeurs à l'intérieur d'une application :
- Un contrôleur HTTP ou groupe de handlers
- Un service de domaine qui possède une tranche de logique métier
- Un repository ou couche d'accès aux données
- Un client encapsulant une API externe
- Un middleware, intercepteur ou worker de fond
Le mot clé est regroupement. Un composant est une abstraction au-dessus du code, pas une classe ou un fichier unique. Le composant OrderService peut s'étendre sur une douzaine de fichiers, mais conceptuellement c'est une seule chose : la partie du container responsable de la logique métier des commandes. Comme le dit la définition du glossaire, un composant C4 est "un regroupement de code de plus haut niveau avec une responsabilité unique" -- pas une correspondance 1:1 avec une classe du langage de programmation.
Ce à quoi le diagramme de composants répond
- Comment ce container est-il structuré en interne ?
- Quel composant possède quelle responsabilité ?
- Comment les composants collaborent-ils pour traiter une requête ?
- D'où partent les appels vers les bases de données et les systèmes externes ?
Ce qu'il omet délibérément
- Les classes, interfaces et fonctions individuelles (c'est le niveau 4, le diagramme de code)
- Les internes des autres containers
- Les détails de déploiement et d'infrastructure
Un container par diagramme, des composants uniquement. Si vous vous surprenez à dessiner des classes, vous avez zoomé trop loin.
Diagramme de composants C4 vs. diagramme de composants UML
C'est une confusion constante, parce qu'UML possède aussi quelque chose appelé "diagramme de composants" -- et ce n'est pas la même chose.
Un diagramme de composants UML modélise des composants logiciels comme des unités avec interfaces fournies et requises (la fameuse notation sucette/prise), en insistant souvent sur le packaging physique, les artefacts et les relations de déploiement. Il vient avec des règles de notation formelles et un métamodèle précis.
Un diagramme de composants C4 est plus souple et plus pragmatique. C'est simplement le niveau 3 d'une hiérarchie de zoom : des boîtes pour les composants, des flèches pour les relations, une courte description sur chacune. Il n'y a aucune notation spéciale à apprendre. La valeur vient de la hiérarchie -- chaque boîte de composant vit dans un container spécifique, qui vit dans un système spécifique -- pas de la notation elle-même.
En pratique : si quelqu'un demande un "diagramme de composants" dans un contexte C4, il veut une carte structurelle des internes d'un container qu'un nouveau développeur peut lire en deux minutes. S'il veut des interfaces sucettes et des stéréotypes <<artifact>>, il demande de l'UML.
Quand le niveau 3 vaut-il la peine d'être maintenu ?
Voici la réponse honnête que la plupart des guides évitent : le niveau 3 est le niveau avec le pire ratio effort/stabilité de tout le modèle C4.
Les diagrammes de contexte changent quelques fois par an. Les diagrammes de containers changent quand vous ajoutez ou supprimez un service -- peut-être une fois par mois. Les diagrammes de composants changent chaque fois que quelqu'un refactorise un package, extrait un service ou renomme un module. Si vous les maintenez à la main, vous vous engagez à un jardinage permanent, et dès que vous arrêtez, le diagramme commence à mentir.
Soyez donc délibéré sur l'endroit où vous investissez cet effort.
Créez un diagramme de composants quand :
- Le container est réellement complexe. Une API backend avec 15 packages, plusieurs couches et des frontières non évidentes mérite une carte. Un service CRUD à trois endpoints, non.
- La structure incarne une conception délibérée. Si vous utilisez l'architecture hexagonale, CQRS ou un découpage en couches propre, le diagramme de composants rend la structure voulue explicite -- et vous donne quelque chose à montrer quand une pull request la viole.
- Plusieurs équipes touchent au même container. Du code partagé nécessite un modèle mental partagé.
- L'onboarding est un goulot d'étranglement. Si les nouveaux développeurs mettent des semaines à se repérer dans un container, un diagramme de composants se rentabilise dès la première embauche.
Évitez-le quand :
- Le container est petit et son arborescence de dossiers est auto-explicative.
- Le container est un outil tiers (on ne dessine pas les internes de Redis).
- Personne ne s'engagera à le garder à jour. Un diagramme de composants obsolète est pire que pas de diagramme du tout -- il envoie les développeurs avec assurance vers du code qui n'existe plus.
C'est exactement pourquoi le niveau 3 est le niveau que la plupart des équipes sautent ou automatisent. Générer les composants à partir de la structure réelle du code -- et les vérifier contre elle -- supprime la taxe de maintenance qui tue les diagrammes dessinés à la main. On y revient plus bas.
Exemple concret : à l'intérieur d'un container API
Rendons cela concret. Reprenons la plateforme e-commerce de notre guide du modèle C4 et zoomons dans un seul container : l'API Commandes (Go). Au niveau 2, c'est une boîte. Au niveau 3, elle s'ouvre en composants.
Les composants
| Composant | Responsabilité |
|---|---|
| Auth Middleware | Valide les tokens JWT sur les requêtes entrantes, injecte l'identité utilisateur dans le contexte de la requête |
| Order Controller | Endpoints REST pour créer, lire et annuler des commandes ; validation des requêtes et sérialisation des réponses |
| Admin Controller | Endpoints REST pour la gestion back-office des commandes (remboursements, changements de statut manuels) |
| Order Service | Logique métier centrale : cycle de vie des commandes, règles de prix, vérification du stock, orchestration des paiements |
| Order Repository | Couche d'accès aux données ; persiste et interroge les commandes en SQL |
| Payment Client | Encapsule l'API Stripe ; gère l'autorisation, la capture et les remboursements |
| Email Adapter | Envoie les emails transactionnels (confirmation de commande, suivi d'expédition) via SendGrid |
| Event Publisher | Publie les événements de domaine (OrderPlaced, OrderCancelled) vers Kafka |
Les relations
[Auth Middleware] --> [Order Controller] : Transmet les requêtes authentifiées
[Auth Middleware] --> [Admin Controller] : Transmet les requêtes authentifiées (rôle admin)
[Order Controller] --> [Order Service] : Délègue les opérations métier
[Admin Controller] --> [Order Service] : Délègue les opérations back-office
[Order Service] --> [Order Repository] : Lit/écrit les commandes
[Order Service] --> [Payment Client] : Autorise et capture les paiements
[Order Service] --> [Email Adapter] : Déclenche les emails transactionnels
[Order Service] --> [Event Publisher] : Émet les événements de domaine
[Order Repository] --> [Base Commandes (PostgreSQL)] : SQL
[Payment Client] --> [Passerelle de paiement (Stripe)] : HTTPS/REST
[Email Adapter] --> [Service email (SendGrid)] : HTTPS/REST
[Event Publisher] --> [File de messages (Kafka)] : Publie les événements
Notez que la base de données, Stripe, SendGrid et Kafka apparaissent en bordure. Ce ne sont pas des composants de ce container -- ce sont des containers voisins et des systèmes externes -- mais montrer d'où partent les appels sortants est précisément ce qui rend le diagramme utile.
Ce que ce diagramme apprend à un nouveau développeur
En trente secondes, un développeur qui rejoint cette équipe apprend :
- Le chemin d'une requête : middleware → contrôleur → service → repository. Il y a exactement un endroit où vit la logique métier, et ce n'est pas le contrôleur.
- Les frontières : tous les appels externes passent par des adaptateurs dédiés (
Payment Client,Email Adapter). Si vous devez parler à Stripe, vous étendez le client ; vous n'importez pas le SDK dans un contrôleur. - Les effets de bord : les commandes produisent des événements sur Kafka et des emails via SendGrid. Si un email n'est pas envoyé, vous savez quels deux composants vérifier.
- Où ajouter du code : une nouvelle fonctionnalité "carte cadeau" nécessite clairement des changements dans le contrôleur, le service, et peut-être un nouveau client -- et le diagramme montre le pattern à suivre.
Ce dernier point est sous-estimé. Un diagramme de composants ne se contente pas de décrire la structure -- il la prescrit. Il dit aux contributeurs à quoi ressemble "cohérent avec cette codebase".
Erreurs courantes avec les diagrammes de composants
Faire correspondre une classe à un composant
L'erreur la plus fréquente. Si votre container a 80 classes et que votre diagramme de composants a 80 boîtes, vous avez dessiné un diagramme de classes avec des étapes en plus. Les composants sont des regroupements : OrderController (un composant) peut couvrir cinq classes de handlers. Visez 5 à 15 composants par container. Au-delà de 20, vos abstractions sont trop fines -- ou votre container en fait trop.
Documenter chaque container au niveau 3
La symétrie est tentante : "nous avons 12 containers, donc il nous faut 12 diagrammes de composants." Résistez. La plupart de ces diagrammes ne seront jamais lus et jamais mis à jour. Documentez les deux ou trois containers où la complexité fait réellement mal, et laissez l'arborescence des dossiers parler pour le reste.
Laisser le diagramme pourrir
Le niveau 3 dérive plus vite que tous les autres niveaux. Un diagramme de composants dessiné en janvier décrit un container qui n'existe probablement plus en juin. Chaque refactoring, chaque package extrait, chaque module renommé élargit l'écart. Et un diagramme faux mais sûr de lui est pire que pas de diagramme : il envoie les développeurs chercher des composants supprimés il y a deux trimestres. Si vous ne pouvez pas automatiser l'entretien, mettez au moins "mettre à jour le diagramme de composants" dans la checklist de PR de ce container.
Dessiner des composants sans responsabilités
Une boîte étiquetée OrderManager sans description, c'est du bruit. Chaque composant doit porter une phrase de responsabilité ("Valide les tokens JWT et injecte l'identité utilisateur"). Si vous ne pouvez pas écrire cette phrase, la frontière du composant est probablement mauvaise.
Montrer des détails d'implémentation au lieu de la structure
Génériques, design patterns, utilitaires -- rien de tout cela n'appartient au niveau 3. Si la partie intéressante d'un composant est comment il est implémenté, c'est le travail du diagramme de code (ou, plus souvent, du code lui-même).
Comment Archyl garde les diagrammes de composants exacts
Tout ce qui précède mène à la même conclusion : les diagrammes de composants sont précieux, mais les maintenir à la main est une partie perdue d'avance. C'est précisément le problème qu'Archyl a été conçu pour résoudre.
La découverte par IA extrait les composants du code
Au lieu de dessiner les composants à la main, vous connectez votre repository et lancez la découverte par IA. Archyl analyse la structure de votre code -- packages, modules, couches, conventions de nommage -- et propose un modèle C4, y compris les composants à l'intérieur de chaque container et les relations entre eux. Un service Go avec des packages handlers/, service/ et repository/ ressort exactement comme le diagramme de composants montré dans l'exemple ci-dessus. Vous passez en revue les suggestions, les acceptez ou les ajustez, et vous avez un modèle de niveau 3 en quelques minutes.
La détection de drift signale les divergences
C'est la partie qui maintient le niveau 3 en vie. Parce qu'Archyl lie les composants à des fichiers et répertoires réels de votre repository, il peut vérifier en continu que les composants documentés existent toujours dans le code. Quand quelqu'un supprime un package, renomme un module ou restructure une couche, le score de drift baisse et les composants concernés sont signalés. Votre diagramme de composants cesse d'être un instantané et devient un contrat surveillé.
Architecture as Code
Si vous préférez des définitions explicites à la découverte, Archyl permet de définir votre modèle C4 -- systèmes, containers, composants et relations -- en YAML versionné dans votre repository. Votre diagramme de composants est versionné, relu en pull request et rendu automatiquement. Combiné à la détection de drift, cela vous donne une documentation de niveau 3 avec les caractéristiques de maintenance du code.
FAQ
Quelle est la différence entre un diagramme de composants C4 et un diagramme de composants UML ?
Un diagramme de composants UML est une notation formelle avec interfaces fournies/requises, artefacts et stéréotypes, centrée sur la modélisation des composants comme unités packagées. Un diagramme de composants C4 est le niveau 3 de la hiérarchie de zoom C4 : une vue pragmatique en boîtes et flèches des composants à l'intérieur d'un container spécifique. Le C4 n'impose aucune notation formelle -- sa valeur vient de la hiérarchie cohérente (système → container → composant → code), pas des symboles.
Un composant, est-ce la même chose qu'une classe ?
Non. Un composant C4 est un regroupement cohésif de code derrière une interface bien définie -- il peut être implémenté comme une classe, une douzaine de classes, un package ou un module. Si votre diagramme de composants a une boîte par classe, vous êtes descendu un niveau de zoom trop bas.
Chaque container a-t-il besoin d'un diagramme de composants ?
Non, et essayer de documenter chaque container au niveau 3 est l'un des moyens les plus rapides d'abandonner le C4. Créez des diagrammes de composants uniquement pour les containers complexes, partagés entre équipes ou centraux pour l'onboarding. Pour le reste, le diagramme de containers plus une arborescence lisible suffisent.
Combien de composants un diagramme de composants doit-il montrer ?
Environ 5 à 15. En dessous de 5, le diagramme n'apprend probablement rien que le diagramme de containers ne disait déjà. Au-dessus de 20, soit vos frontières de composants sont trop fines, soit le container lui-même devrait être découpé.
Envie de diagrammes de composants qui restent exacts ? Essayez Archyl gratuitement et générez un modèle C4 -- composants inclus -- à partir de votre codebase en quelques minutes. Ou continuez la lecture : Qu'est-ce que le modèle C4 ? Guide complet | Guide du diagramme de containers C4 | Guide du diagramme de code C4 | Diagramme de composants dans le glossaire.