Leichtgewichtige Architekturdokumentation mit ADRs
Erreicht eine Software-Anwendung eine gewisse Größe, ist eine Dokumentation der einzelnen Komponenten und deren Zusammenspiel sinnvoll. Auch das Festhalten von Architektur-Entscheidungen ist wichtig, um auch Monate oder Jahre später noch nachvollziehen zu können, warum eine bestimmte Lösung gewählt wurde. Zukünftige Kolleg:innen und euer zukünftiges Ich werden es euch danken.
Eine leichtgewichtige Methode, um Architektur-Entscheidungen zu dokumentieren, stellen Architectural Decision Records, kurz ADRs, dar.
Architektur-Dokumentation
Jedes Stück Software hat auch eine Software-Architektur. Ob diese aktiv herbeigeführt wird oder während der Entwicklung “passiert” ist, hängt von den Umständen und Anforderungen ab. Um Entscheidungen, die man auf dem Weg zum aktuellen Stand der Software getroffen hat, auch im Nachhinein noch nachvollziehen und ggf. bewerten zu können, ist eine Architektur-Dokumentation, oder zumindest eine Dokumentation der wichtigsten Entscheidungen, sinnvoll. Häufig werden solche Entscheidungen in einem Wiki, Confluence oder Word-Dokument festgehalten. Die Dokumentation erfolgt damit außerhalb des eigentlichen Quellcodes und unstrukturiert, was die Pflege und Aktualisierung erschwert. Mit arc42 oder Structurizr existieren Frameworks, um unterschiedliche Aspekte einer Software und deren Architektur strukturiert zu dokumentieren. Für Projekte, die keine derart umfangreiche Dokumentation benötigen, bieten sich ADRs als leichtgewichtige Lösung an.
Architectural Decision Records
Das Ziel von Architectural Decision Records
ist es nicht, die gesamte Architektur einer Software zu beschreiben oder widerzuspiegeln, sondern Entscheidungen, die zu der aktuellen Architektur geführt haben, festhalten.
ADRs
halten Architektur-Entscheidungen in reinen Textdateien fest und geben lediglich das Format vor. Jede Entscheidung erhält eine eigene Datei und eine fortlaufende Nummer. Für eine einfache Formatierungen wird Markdown verwendet. Die Dateien sind Teil des Quellcode-Repositories und unterliegen damit auch der Versionskontrolle. ADRs können damit auch per Pull-Request eingebracht und diskutiert werden.
Auch wenn der Name den Kontext Architektur
setzt, lassen sich ADRs für eine Vielzahl von technischen und nicht-technischen Entscheidungs-Dokumentationen nutzen.
Format
Nach dem Erfinder Michael Nygard bestehen ADRs aus den folgenden Feldern:
Titel: Kurze Beschreibung der Entscheidung.
Context: Beschreibung des Kontexts, in dem die Entscheidung getroffen wurde inkl. der technologischen, politischen oder sozialen Rahmenbedingungen. Die Formulierung ist neutral und beschreibt die vorliegenden Fakten.
Decision: Beschreibt die im zuvor dargestellten Kontext getroffene Entscheidung. Die Formulierung ist aktiv und beschreibt, was getan wird: “Wir werden …”.
Status: Der Status der Entscheidung. Mögliche Werte sind proposed
, accepted
, deprecated
oder superseded
.
Consequences: Beschreibt den resultierenden Zustand nach der Entscheidung. Es werden sowohl positive als auch negative Konsequenzen aufgeführt.
Ein solches ADR-Dokument hat eine Länge von ein bis zwei Seiten. Es stellt eine Kommunikation mit zukünftigen Entwickler:innen oder uns selber dar. Daher ist es wichtig, dass die Dokumentation verständlich und nachvollziehbar ist und nicht nur eine Stichpunktliste enthält. Für den Dateinamen schlägt Nygard ein Format vor: doc/arch/adr-NNN.md
. Über den eindeutigen Bezeichner kann man einzelne ADRs referenzieren, etwa wenn spätere Entscheidungen auf einer vorherigen aufbauen oder diese ersetzen.
Ob man für sein Projekt dem hier gezeigten Format folgt oder eine eigene Variante erarbeitet, ist zweitrangig. Wichtig ist, dass das Format über den Projekt-Verlauf hinweg konsistent eingehalten wird. Joel Parker Henderson hat in einem GitHub-Repository eine Reihe von ADR-Templates zusammengetragen.
Beispiel
Der ADR für die Entscheidung über den Einsatz von RabbitMQ als Message Broker könnte wie folgt aussehen:
# ADR-039: RabbitMQ als Message Broker
## Context
Wir benötigen einen Message Broker, um asynchrone Nachrichten
zwischen den einzelnen Komponenten unserer Anwendung auszu-
tauschen. Die Lösung soll ausfallsicher betrieben werden können
und Nachrichten persistent speichern. Die Lösung soll im eigenen
Rechenzentrum gehostet und von unserem Service-Team betrieben
werden. RabbitMQ ist bereits in anderen Projekten im Einsatz
und das Service-Team mit dem Betrieb vertraut.
## Decision
Wir werden RabbitMQ als Message Broker einsetzen. RabbitMQ
erfüllt unsere Anforderungen und ist bereits im Unternehmen
etabliert. Dem Service-Team wird die Verantwortung für den
Betrieb übertragen. Wir teilen dem Service-Team das erwartete
Nachrichten-Aufkommen mit.
## Status
accepted
## Consequences
Aufgrund der Entscheidung muss im Software-Team Know-How für
den Einsatz von RabbitMQ aufgebaut werden. Das Service-Team
unterstützt das Software-Team bei der Integration. Der
angedachte Einsatz von asynchronen Nachrichten zwischen den
Komponenten der Anwendung kann umgesetzt werden.
Mit einem solchen Dokument ist auch im Nachhinein nachvollziehbar, warum RabbitMQ
und nicht etwa Azure Service Bus
eingesetzt wird.
Werkzeuge
Da es sich bei ADRs um eine strukturierte Variante von Dokumentation handelt, haben sich eine Reihe von Werkzeugen etabliert.
adr-tools
Nat Pryce hat mit adr-tools ein Command Line Tool zum Arbeiten mit ADRs entwickelt. Damit ist es möglich, neue ADRs im von Michael Nygard beschriebenen Format anzulegen.
$ adr init doc/adrs
doc/adrs/0001-record-architecture-decisions.md
$ cat doc/adrs/0001-record-architecture-decisions.md
# 1. Record architecture decisions
Date: 2023-12-28
## Status
Accepted
## Context
We need to record the architectural decisions made on this project.
## Decision
We will use Architecture Decision Records, as [described by Michael Nygard]
(http://thinkrelevance.com/blog/2011/11/15/documenting-architecture-decisions).
## Consequences
See Michael Nygard's article, linked above. For a lightweight ADR toolset,
see Nat Pryce's [adr-tools](https://github.com/npryce/adr-tools).
Neue ADRs können mit adr new
angelegt werden.
$ adr new Write Blog Post about ADRs
doc/adrs/0002-write-blog-post-about-adrs.md
Über weitere Befehle können ADRs verknüpft, aufgelistet und Inhaltsverzeichnisse generiert werden.
$ adr generate toc
# Architecture Decision Records
* [1. Record architecture decisions](0001-record-architecture-decisions.md)
* [2. Write Blog Post about ADRs](0002-write-blog-post-about-adrs.md)
adr-viewer
adr-viewer generiert aus ADR-Dateien eine HTML-Seite. Damit kann man ADRs etwa in seine CI/CD-Pipeline integrieren und die Dokumentation automatisch aktualisieren.
$ pip install adr-viewer
$ adr-viewer --adr-path doc/adrs --output doc/adrs.html
Die generierte Seite bietet eine Übersicht über alle ADRs und ermöglicht die Navigation zwischen den einzelnen Dokumenten. Die unterschiedlichen Status werden farblich hervorgehoben.