Template ADR et exemples : des formats prêts à copier
La réunion durait depuis deux heures. Nous débattions pour savoir s'il fallait utiliser PostgreSQL ou MongoDB pour un nouveau service. Les arguments fusaient dans tous les sens : intégrité relationnelle, schémas flexibles, familiarité de l'équipe, complexité opérationnelle.
Puis quelqu'un a lancé : « On n'a pas eu exactement cette discussion l'an dernier pour le service utilisateurs ? »
Silence. Si. Un an plus tôt, nous avions passé tout autant de temps sur la même question et choisi PostgreSQL. Personne ne se souvenait du raisonnement, et l'ingénieur qui avait mené cette discussion avait quitté l'entreprise. Nous refaisions donc le même débat de zéro.
C'est à ce moment-là que nous avons commencé à écrire des Architecture Decision Records. Cet article est la partie copier-coller : trois templates, quand utiliser chacun, et trois de nos propres décisions remplies.
Qu'est-ce qu'un ADR ?
Un architecture decision record est un court document qui consigne une seule décision d'architecture. Pas un document de conception qui couvre tout un système, juste une décision :
- Ce que nous avons décidé
- Pourquoi nous l'avons décidé
- Quelles alternatives nous avons envisagées
- Quelles en sont les conséquences
Un ADR doit tenir sur une ou deux pages. S'il est plus long, vous documentez probablement plus d'une décision. Le guide complet couvre quand en écrire un, le cycle de vie et les erreurs que font les équipes ; cet article s'en tient aux formats.
Le template minimal (Nygard)
Michael Nygard a proposé le format que la plupart des équipes utilisent encore dans un article de 2011. Cinq parties : un titre qui est un court groupe nominal, un statut, le contexte (« les forces en jeu »), la décision (« notre réponse à ces forces ») et les conséquences (« le contexte résultant, après application de la décision »). Ses statuts sont Proposé, Accepté, Déprécié et Remplacé.
# ADR-NNNN : Court groupe nominal
## Statut
Proposé | Accepté | Déprécié | Remplacé par ADR-XXXX
## Contexte
Quelles forces sont en jeu ? Techniques, organisationnelles, délais, budget.
Soyez précis : chiffres, contraintes, qui est concerné.
## Décision
Nous allons ...
## Conséquences
Ce qui devient plus facile, ce qui devient plus difficile, ce qu'il faut désormais surveiller.
Nous y ajoutons une section : Alternatives envisagées, entre Décision et Conséquences. C'est la partie qui fait gagner le plus de temps plus tard, car la question qu'on vous pose un an après est rarement « qu'avons-nous choisi ? » et presque toujours « pourquoi n'avons-nous pas choisi X ? »
## Alternatives envisagées
### Option B
- Avantages : ...
- Inconvénients : ...
- Pourquoi rejetée : ...
MADR
MADR (Markdown Architectural Decision Records) est un template plus structuré, maintenu sur adr.github.io/madr. La version actuelle est la 4.0.0, publiée le 17 septembre 2024. Il place les métadonnées dans un frontmatter YAML et fait des options et de leurs compromis des sections explicites plutôt que de la prose.
---
status: proposé | rejeté | accepté | déprécié | remplacé par ADR-XXXX
date: AAAA-MM-JJ
decision-makers: ...
consulted: ...
informed: ...
---
# Titre court du problème résolu et de la solution choisie
## Contexte et énoncé du problème
Deux ou trois phrases, ou une courte histoire. Idéalement formulé comme une question.
## Facteurs de décision
* Facteur 1
* Facteur 2
## Options envisagées
* Option A
* Option B
* Option C
## Résultat de la décision
Option choisie : "Option A", parce que ...
### Conséquences
* Bien, parce que ...
* Mauvais, parce que ...
### Confirmation
Comment nous vérifierons que la décision est appliquée (revue, test, fitness function).
## Avantages et inconvénients des options
### Option A
* Bien, parce que ...
* Mauvais, parce que ...
## Informations complémentaires
Liens, décisions liées, quand la revoir.
Dans MADR, toutes les sections après Options envisagées et Résultat de la décision sont optionnelles. Supprimez celles que vous n'utilisez pas plutôt que de laisser des titres vides.
Y-statement
Le Y-statement fait tenir une décision en une seule phrase. Il vient d'Uwe Zdun, Olaf Zimmermann et leurs collègues (« Sustainable Architectural Design Decisions », IEEE Software, 2013) :
Dans le contexte de <cas d'usage ou composant>,
face à <préoccupation ou exigence>,
nous avons choisi <option>
(et écarté <autres options>),
pour obtenir <qualité ou bénéfice>,
en acceptant que <inconvénient>.
Il est trop court pour porter une vraie section de contexte, et c'est tout l'intérêt. Utilisez-le pour les décisions qui ne méritent pas une page, comme ligne de résumé en tête d'un ADR plus long, ou comme format d'entrée dans un journal de décisions.
Quel format utiliser
| Format | Utilisez-le quand | Attention à |
|---|---|---|
| Nygard (plus alternatives) | Vous débutez, ou la plupart des décisions ont un gagnant évident et quelques options rejetées | Les sections de contexte qui tournent à la dissertation |
| MADR | Les décisions sont disputées, plusieurs personnes doivent valider, ou vous voulez des options et des facteurs comparables d'un ADR à l'autre | Remplir chaque section optionnelle par habitude |
| Y-statement | Petites décisions, journal de décisions, ou résumé d'une ligne en tête d'un ADR plus long | L'utiliser pour des décisions qui demandent une vraie section de contexte |
Choisissez-en un pour le dépôt et tenez-vous-y. Des formats mélangés sont plus difficiles à parcourir que n'importe quel format unique n'est difficile à écrire.
Exemple 1 : ADR-0042, PostgreSQL pour l'order service
C'est la décision de l'histoire d'ouverture, au format Nygard avec notre section Alternatives envisagées.
# ADR-0042 : Utiliser PostgreSQL pour l'Order Service
## Statut
Accepté
## Contexte
L'order service a besoin d'un stockage persistant pour les données de
commande. Nous prévoyons de traiter 50 000 commandes par jour au départ,
et 500 000 d'ici deux ans. Les commandes ont une structure bien définie
mais pourront avoir besoin de champs de métadonnées supplémentaires avec
le temps. L'équipe a l'expérience des bases relationnelles et des bases
orientées documents.
## Décision
Nous utiliserons PostgreSQL 15 comme base de données principale de l'order service.
Nous avons choisi PostgreSQL parce que :
- La conformité ACID est requise pour les données de commande financières
- Les colonnes JSON apportent de la flexibilité de schéma pour les métadonnées
- Notre équipe infrastructure a l'expérience opérationnelle de PostgreSQL
- Les patterns de requêtes se prêtent bien à une modélisation relationnelle
## Alternatives envisagées
### MongoDB
- Avantages : stockage JSON natif, scaling horizontal plus simple, évolution de schéma flexible
- Inconvénients : garanties de cohérence plus faibles, équipe moins familière de son exploitation,
outillage supplémentaire nécessaire pour les transactions
### DynamoDB
- Avantages : entièrement managé, exploitation minimale, excellente scalabilité
- Inconvénients : dépendance à AWS, patterns de requêtes limités à l'accès par clé
de partition/tri, coût imprévisible à grande échelle
## Conséquences
### Positives
- Fortes garanties d'intégrité des données
- L'équipe peut réutiliser son expertise PostgreSQL existante
- Caractéristiques opérationnelles bien connues
### Négatives
- Les migrations de schéma demandent plus de planification qu'avec une base documents
- Scaling horizontal plus complexe si nous dépassons la capacité d'un seul nœud
- Sharding applicatif nécessaire si nous atteignons les limites d'échelle
### Risques
- Décision à revoir si le volume de commandes dépasse 1M/jour
- Les requêtes sur colonnes JSON sont moins efficaces qu'avec une base documents native
## Décisions liées
- Voir ADR-0007 pour la raison pour laquelle nous acceptons la cohérence à terme
- Remplace ADR-0003, qui recommandait MongoDB
Soyez précis dans le contexte. « Nous avons besoin de la conformité ACID » aide bien plus le lecteur suivant que « nous avons besoin de fiabilité ». Et soyez honnête dans les conséquences : aucune décision n'est gratuite, et écrire les inconvénients indique aux équipes futures quand il est temps de la revoir.
Exemple 2 : ADR-0007, communication événementielle, en MADR
La décision Kafka avait plus d'options sur la table et plus de personnes impliquées, et c'est là que les facteurs et options explicites de MADR justifient leur place.
---
status: accepté
---
# Utiliser Kafka pour la communication asynchrone entre services
## Contexte et énoncé du problème
Nos microservices communiquent de façon synchrone via HTTP. Cela les
couple fortement, et un service indisponible provoque des pannes en
cascade en amont. Comment les services doivent-ils communiquer quand
l'appelant n'a pas besoin d'une réponse immédiate ?
## Facteurs de décision
* Résilience : la panne d'un service ne doit pas entraîner les autres
* Couplage plus faible entre services
## Options envisagées
* Garder HTTP synchrone
* Communication événementielle avec Apache Kafka
## Résultat de la décision
Option choisie : "Communication événementielle avec Apache Kafka", parce
qu'elle supprime le couplage à l'exécution qui provoque les pannes en cascade.
### Conséquences
* Bien, parce que les services deviennent plus résilients aux pannes des autres
* Mauvais, parce que nous passons d'une cohérence forte à une cohérence à terme
* Mauvais, parce que nous exploitons désormais un cluster Kafka
* Mauvais, parce que l'équipe doit être formée aux patterns événementiels
Le statut et le titre sont repris ; les champs date et decision-makers sont omis ici parce que l'enregistrement d'origine ne les avait pas conservés.
Exemple 3 : ADR-0015, un monorepo frontend, en Y-statement
La décision du monorepo tient en une phrase, et cette phrase suffit à répondre à « pourquoi tout est dans un seul dépôt ? »
Dans le contexte de nos 5 applications frontend réparties dans des dépôts séparés,
face aux incompatibilités de versions et au coût de publication de packages pour partager du code,
nous avons choisi un monorepo unique géré avec Nx
(et écarté des dépôts séparés avec une meilleure gestion des packages, ainsi qu'un monorepo sans Nx),
pour obtenir un partage de code simple et une seule pull request qui met à jour le code partagé et tous ses consommateurs,
en acceptant qu'un dépôt plus gros nécessite du cache de build et que des applications puissent se coupler par accident.
Les options rejetées portent leurs raisons dans l'enregistrement complet : des dépôts séparés conservaient le coût de coordination, et un monorepo sans Nx aurait rendu les temps de build prohibitifs.
Où les conserver
Placez les ADR dans le dépôt qu'ils décrivent, dans docs/adr/ ou docs/decisions/ (Nygard suggérait doc/arch/adr-NNN.md). Ils sont versionnés avec le code, ils apparaissent en revue de code, et ils ne peuvent pas se perdre dans un wiki.
Numérotez-les séquentiellement et ne réutilisez jamais un numéro. Quand une décision change, écrivez un nouvel ADR qui remplace l'ancien et mettez à jour le statut de l'ancien, plutôt que de réécrire l'historique.
L'étape que la plupart des équipes sautent consiste à relier un ADR à la partie du système qu'il affecte. Dans Archyl, un ADR porte les champs de Nygard (statut, contexte, décision, conséquences) plus une date et un lien « remplacé par », et se rattache aux systèmes, conteneurs et composants qu'il a façonnés. Quiconque regarde l'order service dans le diagramme C4 voit ADR-0042 à côté : « Pourquoi ce service est-il sur PostgreSQL ? » est à un clic.
Les pièges (écrire les ADR après coup, les laisser s'étendre sur cinq pages, abandonner la pratique après le premier trimestre chargé) sont traités dans le guide complet.
Commencez par un seul
Cette réunion de deux heures sur PostgreSQL contre MongoDB ? La fois suivante où la question est revenue, elle s'est terminée en dix minutes, parce que quelqu'un a trouvé ADR-0042. Les contraintes, les alternatives et le raisonnement étaient tous là. Nous avons confirmé que la décision d'origine s'appliquait toujours et nous sommes passés à autre chose.
Choisissez l'un des templates ci-dessus et collez-le dans docs/adr/0001-record-architecture-decisions.md. Votre premier ADR peut être la décision d'écrire des ADR.
En savoir plus sur la documentation d'architecture : le guide du modèle C4 | Pourquoi la documentation compte | Documenter les parcours utilisateurs