Read in English · Leer en español · Lire en français
Abschnitt 4.5 von 4.8 · Mittelstufe · 22 Min. Lesezeit
Architecture Decision Records
Videolektion
5 Min. · auf Englisch gesprochen, mit UntertitelnNur anhören (Audio)
Transkript lesen
Diagramme zeigen, wie ein System gebaut ist, aber selten, warum. In dieser Lektion lernen Sie, bedeutsame Entscheidungen so festzuhalten, dass ihre Gründe erhalten bleiben, lange nachdem die Beteiligten weitergezogen sind.
Stellen Sie sich vor, Sie ziehen in ein Haus und finden eine Wand, die keinen Zweck zu erfüllen scheint. Reißen Sie sie ein? Hätte der Bauunternehmer einen Zettel hinterlassen, dass diese Wand das Bad im Obergeschoss trägt, wüssten Sie Bescheid. Ein Entscheidungsdokument ist dieser Zettel für Software. Und Zettel werden nie umgeschrieben. Ändern die Eigentümer ihre Meinung, fügen sie einen neuen Zettel hinzu, der sagt, was sich geändert hat und warum.
Ein Architecture Decision Record, kurz ADR, ist ein kurzes Textdokument, das eine bedeutsame Entscheidung festhält: die Situation, die sie erzwang, die abgewogenen Optionen, was gewählt wurde und was daraus folgt. In ihrer Reihenfolge bilden die Records das Entscheidungsprotokoll des Systems. Die schlanke Form stammt aus einem Blogbeitrag von Michael Nygard aus dem Jahr 2011. Sein Problem war die neue Person im Team, die im Code auf eine seltsame Entscheidung stößt. Ohne die Gründe nimmt sie sie entweder blind hin oder ändert sie blind und macht etwas kaputt, dessen Gründe noch gelten.
Nygard schlug fünf Teile vor. Der Titel benennt die Entscheidung, nicht das Problem, mit einer laufenden Nummer, die nie wiederverwendet wird. Der Kontext beschreibt die wirkenden Kräfte in neutraler Sprache: Fakten, nicht die bevorzugte Antwort. Nennen Sie Zahlen, wo es welche gibt. Die Entscheidung steht in ganzen Sätzen im Aktiv, beginnend mit „Wir werden“, damit kein Zweifel bleibt, was entschieden wurde. Der Status zeigt, ob der Record in Kraft ist. Und die Konsequenzen listen alles auf, was folgt: was leichter wird, was schwerer wird und neue Risiken. Ausführlichere Vorlagen wie Markdown Architectural Decision Records führen auch die betrachteten Optionen auf, und genau die wollen spätere Lesende oft am meisten wissen.
Records durchlaufen einen kleinen Lebenszyklus. Ein Record beginnt als „vorgeschlagen“, meist als Pull Request, damit die Diskussion in Review-Kommentaren stattfindet. Wenn die Verantwortlichen zustimmen, wird er als „akzeptiert“ gemergt, und sein Text ist fixiert. Ein abgelehnter Vorschlag bleibt als „abgelehnt“ erhalten. Das ist wertvoll: Wer als Nächstes dieselbe Idee vorschlägt, findet die frühere Begründung. Später kann ein akzeptierter Record veralten, weil er nicht mehr gilt, oder durch einen neuen Record abgelöst werden, mit Links in beide Richtungen. Die zentrale Regel: Bei einem akzeptierten Record ändern sich nur Statuszeile und Links. Ihn zu bearbeiten, würde aus Geschichte Fiktion machen. Neue Überlegungen gehören in einen neuen Record.
Hier ist ein vollständiger Record für die Essenslieferplattform. Der Kontext nennt Zahlen, keine Adjektive. Zur Freitagsspitze erreicht die Bestellbestätigung im neunundneunzigsten Perzentil vier Komma zwei Sekunden, bei einem Ziel von eins Komma fünf. Und ein Ausfall blockierte dreiundzwanzig Minuten lang alle Bestellungen. Dann folgen die Entscheidungstreiber, formuliert, bevor irgendeine Option beurteilt wird. Die Bestätigung darf nicht von anderen Services abhängen, und kein Bestellereignis darf verloren gehen. Drei Optionen werden fair angehört: die Aufrufe behalten und Wiederholungen ergänzen, Ereignisse über einen verwalteten Broker veröffentlichen oder Consumer eine gemeinsame Tabelle abfragen lassen. Die Entscheidung fällt auf Option zwei. Die Zahlungsautorisierung bleibt aber synchron, weil der Kunde das Ergebnis sehen muss. Die Konsequenzen sind ehrlich. Die Bestätigung wartet nicht mehr, aber die Services sind nur noch eventual consistent, ein Broker kostet Geld, und Consumer müssen doppelte Ereignisse verarbeiten. Schließlich sagt die Bestätigung, wie das Team prüft, ob die Entscheidung wirklich trägt: mit einem Lasttest und einer Build-Prüfung.
Nicht jede Entscheidung braucht einen Record. Schreiben Sie einen, wenn eine Entscheidung teuer rückgängig zu machen ist oder eine zentrale Qualität wie Verfügbarkeit oder Kosten betrifft. Schreiben Sie einen, wenn sie andere Teams einschränkt oder umstritten war, damit die Begründung nicht von vorn diskutiert wird. Lokale, billig umkehrbare Entscheidungen, etwa eine Testbibliothek, brauchen keinen. Ein gutes Signal: Wenn innerhalb eines Jahres jemand fragen wird, warum um Himmels willen die das so gemacht haben, schreiben Sie ihn jetzt. Bewahren Sie Records als nummerierte Markdown-Dateien im Code-Repository auf, geprüft in Pull Requests, mit einem kurzen Index, den jemand Neues in fünf Minuten lesen kann.
Records scheitern auf erkennbare Weise. Der erste Fehler ist der nachträglich geschriebene Record, so konstruiert, dass er rational wirkt. Schreiben Sie ihn während der Entscheidung, als Vorschlag. Ein anderer nennt keine echten Alternativen oder fügt eine Strohmann-Option hinzu, die nie funktionieren könnte, damit der Favorit geprüft wirkt. Ein weiterer nennt nur Vorteile. Jede bedeutsame Entscheidung hat Kosten, und einem Protokoll, das sie verschweigt, vertraut bald niemand mehr. Und der letzte ist, akzeptierte Records an den aktuellen Entwurf anzupassen, was genau die Historie zerstört, die das Protokoll bewahren soll.
Der vollständige Abschnitt zeigt den ganzen Record, das Y-Statement in einem Satz und wie Teams Entscheidungen prüfen. Als Nächstes betrachten wir in Abschnitt vier Punkt sechs arc zweiundvierzig und andere Vorlagen für die gesamte Beschreibung. Bis gleich.
Was Sie wissen müssen
- Ein Architecture Decision Record (ADR) hält eine bedeutsame Entscheidung mit ihrem Kontext, den betrachteten Optionen, der Entscheidung und ihren Konsequenzen fest; Michael Nygard machte die schlanke Form 2011 in einem Blogbeitrag bekannt.
- Nygards Format hat Titel, Kontext, Entscheidung, Status und Konsequenzen; der Kontext wird neutral formuliert, die Entscheidung im Aktiv („Wir werden …“), und die Konsequenzen umfassen Kosten ebenso wie Nutzen.
- MADR (Version 4.0.0, 2024) ergänzt Entscheidungstreiber, betrachtete Optionen mit Vor- und Nachteilen sowie die Bestätigung; ein Y-Statement verdichtet eine Entscheidung zu einem Satz: im Kontext von, angesichts, haben wir uns entschieden für, und gegen, um … zu erreichen, und nehmen in Kauf, dass.
- ADRs wechseln von „vorgeschlagen“ zu „akzeptiert“ oder „abgelehnt“ und später zu „veraltet“ oder „abgelöst“; der Inhalt eines akzeptierten ADR wird nie umgeschrieben, weil ein neues, ablösendes ADR die Historie bewahrt.
- ADRs liegen im Code-Repository als nummerierte Markdown-Dateien (zum Beispiel docs/decisions/0012-title.md), werden in Pull Requests geprüft und in einem Entscheidungsprotokoll indexiert.
- Schreiben Sie ein ADR für Entscheidungen, die teuer rückgängig zu machen sind, zentrale Qualitäten betreffen, andere einschränken oder umstritten waren; vermeiden Sie ADRs, die im Nachhinein geschrieben werden, keine echten Alternativen enthalten oder nur positive Konsequenzen nennen.
Was ein ADR ist und welches Problem es löst
Ein Architecture Decision Record (ADR) ist ein kurzes Textdokument, das eine architekturrelevante Entscheidung festhält: die Situation, die sie erzwungen hat, die abgewogenen Optionen, was gewählt wurde und was aus der Wahl folgt. Eine geordnete Sammlung solcher Records bildet das Entscheidungsprotokoll eines Systems. Die Idee, Entscheidungen festzuhalten, ist alt (die Forschung zu Design Rationale reicht Jahrzehnte zurück, und Jeff Tyree und Art Akerman veröffentlichten 2005 in IEEE Software eine ausführliche Entscheidungsvorlage), doch die schlanke Form, die die meisten Teams heute nutzen, stammt aus Michael Nygards Blogbeitrag Documenting Architecture Decisions vom 15. November 2011.
Nygards Ausgangspunkt war ein Problem, das jedes langlebige Team kennt. Eine neue Entwicklerin oder ein neuer Entwickler stößt im Code auf eine Entscheidung, die seltsam aussieht: eine zusätzliche Queue, eine doppelte Tabelle, eine Bibliothek, die heute niemand mehr wählen würde. Ohne zu wissen, warum sie getroffen wurde, bleiben der neuen Person zwei schlechte Möglichkeiten. Sie kann sie blind hinnehmen und damit etwas bewahren, dessen Gründe vielleicht nicht mehr gelten, oder sie blind ändern und damit etwas kaputtmachen, dessen Gründe noch gelten. Nygards Gegenmittel bestand darin, die Gründe zum Zeitpunkt der Entscheidung aufzuschreiben, in einer kleinen Datei neben dem Code, damit die Motivation mit dem System mitwandert. Große Architekturdokumente erreichen das selten, weil niemand sie aktualisiert; ein kurzer Record über eine einzige Entscheidung, einmal geschrieben und nie umgeschrieben, bleibt wahr, weil er nur beansprucht, zu beschreiben, was an einem bestimmten Datum bekannt war und entschieden wurde.
Das baut direkt auf der Anatomie einer Entscheidung aus Kapitel 1: Entscheidungen und Abwägungen auf: Kontext, Optionen, Kriterien, Entscheidung mit Begründung, Konsequenzen und Status. Ein ADR ist einfach diese Anatomie, in einem vorhersehbaren Format aufgeschrieben. Es beantwortet auch die Frage, die Architektur und Design in der Praxis offenlässt: Wenn Architektur die Menge der bedeutsamen Entscheidungen ist, dann ist das ADR-Protokoll das, was einer Liste der eigenen Architektur für ein Team am nächsten kommt.
Nygards Format
Nygard schlug fünf Teile vor. Die meisten Teams verwenden sie noch heute und setzen den Status oft an den Anfang, damit Lesende sofort sehen, ob der Record in Kraft ist. Seine Hinweise, wie man jeden Teil schreibt, sind ebenso wichtig wie die Überschriften.
Die fünf Teile eines ADR nach Nygard
| Teil | Was er enthält | Wie man ihn gut schreibt |
|---|---|---|
| Titel | Eine kurze Nominalphrase, die die Entscheidung benennt, mit einer laufenden Nummer, etwa ADR 12: Bestellereignisse über einen Message Broker. | Benennen Sie die Entscheidung, nicht das Problem: Wer das Protokoll überfliegt, sollte schon am Titel erkennen, was entschieden wurde. |
| Kontext | Die wirkenden Kräfte: das Problem, die relevanten Qualitätsanforderungen und Randbedingungen, technische und organisatorische Fakten und die Spannung zwischen ihnen. | Nygard verlangt wertneutrale Sprache: Beschreiben Sie Fakten und Kräfte, nicht die bevorzugte Antwort. Nennen Sie Zahlen, wo es welche gibt (Spitzenlast, Zielwerte, Daten von Vorfällen). |
| Entscheidung | Die Antwort auf diese Kräfte. | Ganze Sätze im Aktiv, beginnend mit Wir werden …, damit kein Zweifel besteht, was entschieden wurde und von wem. |
| Status | Vorgeschlagen, akzeptiert und später eventuell veraltet oder abgelöst, mit Verweis auf den ersetzenden Record. | Halten Sie ihn aktuell; er ist das einzige Feld, das sich nach der Annahme noch ändert. |
| Konsequenzen | Der Kontext, der sich ergibt, nachdem die Entscheidung umgesetzt ist. | Führen Sie alle Konsequenzen auf, nicht nur die positiven: was leichter wird, was schwerer wird, neue Risiken, neue Arbeit und Optionen, die nun verschlossen sind. |
Nygard schlug außerdem vor, dass ein Record auf ein oder zwei Seiten passen sollte, dass Records fortlaufend nummeriert und Nummern nie wiederverwendet werden und dass sie als einfacher Text im Projekt-Repository liegen. Jede dieser kleinen Regeln hat einen Grund: Kurze Records werden gelesen, stabile Nummern lassen sich in Code-Kommentaren und Commit-Nachrichten zitieren, und einfacher Text im Repository lässt sich wie Code prüfen und versionieren.
Weitere Vorlagen: MADR, Y-Statements und ausführlichere Formen
Nygards Format sagt nichts ausdrücklich über die verworfenen Optionen, und viele Teams stellten fest, dass gerade die Alternativen das sind, was spätere Lesende am meisten wissen wollen. Mehrere Vorlagen ergänzen sie.
MADR (Markdown Architectural Decision Records, gepflegt auf adr.github.io) ist die am weitesten verbreitete strukturierte Vorlage. Die zum Zeitpunkt der Abfassung aktuelle Version ist 4.0.0, veröffentlicht im September 2024. Die vollständige Vorlage hat einen Titel, dann Context and Problem Statement, optional Decision Drivers, Considered Options, Decision Outcome mit den optionalen Unterabschnitten Consequences und Confirmation, optional Pros and Cons of the Options und optional More Information. Metadaten wie Status, Datum, Entscheidende sowie wer konsultiert und wer informiert wurde, können in einen YAML-Header. Zwei Ideen aus MADR lohnen sich auch dann, wenn Sie ein anderes Format verwenden. Entscheidungstreiber machen die Kriterien explizit, bevor die Optionen beurteilt werden; das ist die Disziplin der gewichteten Matrix aus Kapitel 1 in kompakter Form. Confirmation (Bestätigung) sagt, wie das Team prüfen wird, ob die Entscheidung tatsächlich umgesetzt ist und weiterhin gilt, etwa durch ein Review, einen Test oder eine automatisierte Architekturprüfung.
Das Y-Statement, vorgeschlagen von Olaf Zimmermann und Kollegen und erstmals 2012 auf der SATURN-Konferenz vorgestellt, verdichtet eine Entscheidung zu einem einzigen strukturierten Satz: Im Kontext von (einem Anwendungsfall oder einer Komponente), angesichts (eines Anliegens oder einer Qualitätsanforderung) haben wir uns entschieden für (die Option) und gegen (die Alternativen), um … zu erreichen (den Nutzen), und nehmen in Kauf, dass (die Nachteile). Der Name ist ein Wortspiel mit why
(„warum“). Ein Y-Statement eignet sich ideal für eine Zusammenfassung im Entscheidungsprotokoll, eine Folie, einen Code-Kommentar oder die Beschreibung eines Pull Requests; für eine umstrittene Einwegtür ist es meist zu knapp, und Teams bauen es zu einem vollständigen Record aus.
Für regulierte oder sehr große Umgebungen gibt es schwerere Vorlagen. Die Vorlage von Tyree und Akerman aus dem Jahr 2005 ergänzt Felder wie Annahmen, Randbedingungen, verwandte Entscheidungen, verwandte Anforderungen und Implikationen. Sie sind nützlich, wenn Entscheidungen für einen Prüfer auf Anforderungen zurückgeführt werden müssen; für die meisten Produktteams bedeuten sie Aufwand, den niemand liest.
Eine Vorlage wählen
| Vorlage | Umfang | Hält verworfene Optionen fest? | Am besten für |
|---|---|---|---|
| Nygard (2011) | Eine halbe bis zwei Seiten | Nur wenn Sie sie in Kontext oder Konsequenzen aufnehmen | Teams am Anfang; die kleinste Gewohnheit, die funktioniert. |
| MADR 4.0.0 (2024) | Eine bis drei Seiten | Ja: betrachtete Optionen, optional mit Vor- und Nachteilen jeder Option | Die meisten Produktteams; umstrittene Entscheidungen, bei denen Alternativen sichtbar sein müssen. |
| Y-Statement (2012) | Ein Satz | Ja, im Teil und gegen | Zusammenfassungen im Entscheidungsprotokoll, kleine Entscheidungen, Beschreibungen von Pull Requests, Folien. |
| Tyree und Akerman (2005) | Mehrere Seiten | Ja, dazu Annahmen, Randbedingungen und Nachverfolgbarkeit | Regulierte Umgebungen, die Nachverfolgbarkeit bis zu den Anforderungen brauchen. |
Status, Lebenszyklus und warum akzeptierte Records nicht bearbeitet werden
Ein ADR durchläuft eine kleine Zahl von Zuständen. Es beginnt als vorgeschlagen, meist als Pull Request, der die Datei hinzufügt, sodass die Diskussion in Review-Kommentaren stattfindet. Wenn die Verantwortlichen zustimmen, wird es als akzeptiert gemergt. Ein Vorschlag, der abgelehnt wird, kann als abgelehnt erhalten bleiben, und das ist wertvoll: Wer als Nächstes dieselbe Idee vorschlägt, findet die frühere Begründung. Später kann ein akzeptierter Record veraltet sein (die Entscheidung gilt nicht mehr, etwa weil die Komponente stillgelegt wurde) oder durch einen neueren Record, der ihn ersetzt, abgelöst werden, mit Links in beide Richtungen. MADR nennt dieselben Zustände: proposed, rejected, accepted, deprecated und superseded.
Die zentrale Regel lautet: Der Inhalt eines akzeptierten Records wird nicht umgeschrieben. Ändert das Team seine Meinung, schreibt es ein neues ADR, das das alte ablöst, und ändert am alten Record nur die Statuszeile, die nun nach vorn verweist. Die Gründe sind praktischer Natur. Erstens ist der Record ein Beleg dafür, was zu einem Zeitpunkt bekannt war und entschieden wurde; ihn im Nachhinein zu bearbeiten, macht aus Geschichte Fiktion und zerstört das Vertrauen, das das Protokoll nützlich macht. Zweitens erklärt der alte Record, warum das System eine Zeit lang so aussah, wie es aussah, und das zählt, wenn man alte Daten debuggt oder alten Code liest. Drittens zwingt ein neuer Record das Team, zu benennen, was sich am Kontext geändert hat, und das ist oft die wichtigste Erkenntnis. Kleine Korrekturen (ein Tippfehler, ein defekter Link) sind harmlos; die Entscheidung, die Gründe oder die Konsequenzen zu ändern, ist es nicht. Martin Fowlers Beschreibung der Praxis sagt dasselbe: Ein akzeptierter Record wird nicht wieder geöffnet; stattdessen wird ein ablösender Record geschrieben.
Der Lebenszyklus eines ADR
Wo man ADRs aufbewahrt
Bewahren Sie ADRs im Repository des Codes auf, für den sie gelten, als Textdateien (meist Markdown), eine Entscheidung pro Datei, mit laufender Nummer und kurzem Slug im Dateinamen. Zwei Verzeichniskonventionen sind verbreitet: doc/adr, der Standard von Nat Pryces Kommandozeilenwerkzeug adr-tools, und docs/decisions, von MADR empfohlen, mit Namen wie 0012-publish-order-events-through-broker.md. Thoughtworks setzte schlanke ADRs in den Adopt-Ring seines Technology Radar (zuletzt 2018) und empfahl ausdrücklich die Versionsverwaltung statt eines Wikis, damit die Records mit dem Code, den sie beschreiben, Schritt halten.
Records neben dem Code aufzubewahren, hat konkrete Vorteile. Sie werden in denselben Pull Requests geprüft wie der Code, der sie umsetzt, sie werden mit ihm versioniert und verzweigt, man findet sie mit denselben Suchwerkzeugen, und Code kann auf sie verweisen: Ein Kommentar wie siehe ADR-0012
über einem Outbox-Relay sagt dem nächsten Leser, wo die Gründe stehen. Entscheidungen, die viele Repositorys betreffen, etwa die organisationsweite Wahl eines Identity Providers, brauchen ein eigenes Zuhause; ein eigenes Architektur-Repository mit denselben Konventionen funktioniert gut, mit Links aus jeder betroffenen Codebasis.
docs/
decisions/
README.md <- the decision log (index)
0001-record-architecture-decisions.md
0004-use-hosted-card-fields.md
0007-use-managed-postgresql-for-orders.md
0012-publish-order-events-through-broker.md
template.md
src/
ordering/
outbox_relay.py # comment: see docs/decisions/0012-...
Welche Entscheidungen ein ADR verdienen
Ein ADR für jede Wahl zu schreiben, begräbt die wichtigen; gar keines zu schreiben, verliert die Gründe. Der Maßstab ist die Bedeutsamkeit, wie in Kapitel 1 definiert: Eine Entscheidung verdient einen Record, wenn sie teuer rückgängig zu machen ist, ein zentrales Qualitätsmerkmal betrifft, eine große Reichweite hat, andere Teams einschränkt oder umstritten war. In der Praxis sind das Entscheidungen wie der primäre Datenspeicher, der Kommunikationsstil zwischen Services, ein Identity Provider, eine Richtlinie zur API-Versionierung, eine Hosting-Plattform, eine Make-or-Buy-Entscheidung und Konventionen, deren Verletzung teuer ist (wie Geldbeträge dargestellt, wie Zeitzonen gespeichert werden). Dazu gehören auch Entscheidungen, etwas nicht zu tun, das immer wieder vorgeschlagen wird, etwa vorerst keinen Cache einzuführen.
Entscheidungen, die lokal sind, billig rückgängig zu machen und außerhalb eines Moduls unsichtbar, brauchen meist keinen Record: die Wahl einer Assertion-Bibliothek für Tests, der Name einer Klasse, der interne Aufbau einer Komponente. Ein nützliches Signal ist die Frage, die jemand Neues stellen würde: Wenn innerhalb eines Jahres vermutlich jemand fragt Warum um Himmels willen haben die das so gemacht?
, schreiben Sie den Record jetzt, solange die Gründe frisch sind.
Entscheidungshilfe
Entscheidungshilfe: Braucht diese Entscheidung ein ADR?
Stellen Sie diese Fragen der Reihe nach, wenn in einer Designdiskussion oder einem Code-Review eine technische Entscheidung ansteht.
- Würde es in einem Jahr mehr als ein paar Tage Arbeit, eine Datenmigration oder Änderungen anderer Teams kosten, diese Entscheidung rückgängig zu machen?JaSchreiben Sie ein ADR. Es ist eine Einwegtür oder kommt ihr nahe.NeinWeiter zur nächsten Frage.
- Beeinflusst sie spürbar ein Qualitätsmerkmal, das den Stakeholdern wichtig ist (zum Beispiel Verfügbarkeit, Latenz, Sicherheit oder Kosten), oder eine Randbedingung wie Regulierung?JaSchreiben Sie ein ADR und verknüpfen Sie es mit dem Qualitätsszenario, dem es dient.NeinWeiter zur nächsten Frage.
- War sie umstritten, oder hat das Team eine Option verworfen, die vermutlich erneut vorgeschlagen wird?JaSchreiben Sie ein kurzes ADR (ein Y-Statement kann genügen), damit die Begründung nicht von Grund auf neu diskutiert wird.NeinWeiter zur nächsten Frage.
- Wird jemand Neues wahrscheinlich auf das Ergebnis schauen und fragen, warum es so gemacht wurde?JaSchreiben Sie ein kurzes ADR oder zumindest einen Code-Kommentar und eine Commit-Nachricht, die den Grund erklären.NeinKein ADR nötig. Eine klare Commit-Nachricht und der Code selbst genügen.
Ein vollständiges ausgearbeitetes ADR
Die Essenslieferplattform, die sich durch dieses Kapitel zieht, hat Apps für Kunden, Restaurants und Kuriere, einen Bestellservice, Zahlungen über einen externen Zahlungsanbieter, Kurierdisposition und Benachrichtigungen. Der folgende Record folgt der MADR-Struktur, leicht gekürzt. Achten Sie darauf, wie der Kontext Zahlen und Daten statt Adjektiven nennt, wie die Treiber vor den Optionen stehen, wie die verworfenen Optionen fair angehört werden und wie die Konsequenzen echte Kosten enthalten. Die Entscheidung selbst (asynchrones Messaging für Bestellereignisse) wird in Kapitel 6: ereignisgesteuerte Architektur gründlich behandelt; hier geht es darum, wie sie festgehalten wird.
# ADR-0012: Publish order events through a managed message broker
- Status: Accepted
- Date: 2026-09-14
- Deciders: ordering team lead, platform lead, principal architect
- Consulted: restaurant, courier and notifications teams; SRE
- Related: ADR-0007 (managed PostgreSQL for the order service)
## Context and problem statement
When a customer's payment succeeds, the ordering service calls the restaurant,
courier-dispatch and notification services synchronously over HTTP before it
confirms the order. On Friday evenings (peak about 40 orders/s) p99 order
confirmation time reaches 4.2 s against our target of 1.5 s (scenario QS-3).
On Friday 21 August a notification-service outage blocked all new orders for
23 minutes. Two new consumers (loyalty points, analytics) want order data.
## Decision drivers
- Order confirmation must not depend on notification or dispatch availability.
- p99 confirmation under 1.5 s at three times today's peak.
- No order event may be lost, even if a service crashes mid-request.
- New consumers should not require changes to the ordering service.
- The platform team has three people; operational load must stay small.
## Considered options
1. Keep synchronous calls; add timeouts, retries and circuit breakers.
2. Publish events to a managed message broker using a transactional outbox.
3. Let consumers poll a shared "order_events" table in the order database.
## Decision outcome
Chosen option: 2. We will publish OrderPlaced, OrderAccepted, OrderPickedUp,
OrderDelivered and OrderCancelled events to our cloud provider's managed
broker. The ordering service writes each event to an outbox table in the
same database transaction as the order; a relay publishes it. Payment
authorisation stays synchronous, because the customer must see the result.
### Consequences
- Good: confirmation no longer waits for downstream services.
- Good: loyalty and analytics can subscribe without ordering-team work.
- Bad: services become eventually consistent; the restaurant tablet may
show a new order a second or two after the customer's confirmation.
- Bad: a broker to pay for and monitor; consumers must be idempotent
because delivery is at-least-once.
- Neutral: event schemas become public contracts and need versioning.
### Confirmation
Load test at 120 orders/s in staging before go-live; a build check fails
if the ordering service gains an HTTP client for notification or dispatch.
## Pros and cons of the other options
- Option 1: least new infrastructure, but a slow dependency still delays
every order, and each new consumer means another call to add.
- Option 3: no new infrastructure, but couples every consumer to our schema
and adds polling load to the order database (see ADR-0007).
Ausgearbeitetes Beispiel
Ausgearbeitetes Beispiel: dieselbe Entscheidung als Y-Statement
Für das Entscheidungsprotokoll, die Beschreibung eines Pull Requests oder eine Folie schreibt das Team die Entscheidung zusätzlich als ein Y-Statement.
| Y-Statement | Im Kontext der Bestellbestätigung auf der Essenslieferplattform, angesichts langsamer oder nicht verfügbarer nachgelagerter Services, die Bestellungen zu Spitzenzeiten blockieren, haben wir uns entschieden für die Veröffentlichung von Bestellereignissen über einen verwalteten Message Broker mit Transactional Outbox und gegen synchrone Aufrufe mit Circuit Breakern sowie Consumer, die eine gemeinsame Tabelle abfragen, um eine Bestellbestätigung, die nicht von Benachrichtigungs-, Dispositions- oder Restaurantservices abhängt, und neue Consumer ohne Änderungen am Bestellservice zu erreichen, und nehmen in Kauf, dass die Services nur noch Eventual Consistency bieten, der Broker betrieben und bezahlt werden muss und jeder Consumer doppelte Ereignisse verarbeiten muss. |
|---|---|
| Was es bewahrt | Den Kontext, das treibende Anliegen, die Wahl, die verworfenen Optionen, den Nutzen und die in Kauf genommenen Kosten: jedes Element des vollständigen Records, auf einen Blick. |
| Was es verliert | Die Zahlen (p99 von 4,2 s, 23-minütiger Ausfall), die Entscheidenden, den Bestätigungsplan und die Gründe gegen jede verworfene Option. Für eine so bedeutsame Entscheidung bleibt der vollständige Record nötig. |
Ein guter Test für jedes ADR ist, ob es sich zu einem sinnvollen Y-Statement verdichten lässt. Wenn Sie die Teile und gegen oder und nehmen in Kauf, dass nicht füllen können, hat der Record vermutlich keine echten Alternativen betrachtet oder seine Kosten verschwiegen.
ADRs prüfen
Weil ein ADR eine Datei im Repository ist, ist der Pull Request der natürliche Review-Mechanismus. Wer es vorschlägt, öffnet ihn mit dem Status vorgeschlagen; die Betroffenen kommentieren; der Record wird überarbeitet; wenn die Verantwortlichen zustimmen, wechselt der Status zu akzeptiert, und er wird gemergt. So bleibt die Diskussion mit dem Record verbunden und für alle sichtbar, die später die Historie lesen.
Wer prüfen muss, hängt davon ab, wie Entscheidungen gesteuert werden. In einem zentralisierten Modell genehmigt ein Architekturgremium bedeutsame Records. Im Advice Process, den Andrew Harmel-Law beschrieben hat (martinfowler.com, 2021), darf jede Person eine Architekturentscheidung treffen, sofern sie vorher den Rat aller wesentlich Betroffenen und von Personen mit einschlägiger Expertise einholt und diesen Rat festhält; wer entscheidet, muss dem Rat nicht folgen, ihn aber anhören. ADRs sind das Rückgrat dieses Prozesses: Der Rat steht im Record, und ein regelmäßiges, offenes Beratungsforum prüft die vorgeschlagenen Records. Governance-Modelle behandelt Kapitel 11: Governance in agilen Organisationen.
Olaf Zimmermanns Checkliste ecADR (2020) gibt Prüfenden eine kompakte Definition of Done für eine Entscheidung. Evidence (Evidenz): Es gibt Grund zur Annahme, dass die Option funktioniert, aus einem Spike, einem Proof of Concept oder bewährter Erfahrung. Criteria (Kriterien): Mindestens zwei Optionen wurden anhand der Anliegen der Stakeholder verglichen. Agreement (Einigung): Die Entscheidung wurde von Fachkollegen hinterfragt, und das Team trägt sie mit. Documentation (Dokumentation): Sie ist festgehalten und mit den Betroffenen geteilt. Realisation and review (Umsetzung und Überprüfung): Die Umsetzung ist geplant, und ein Datum oder Auslöser für die erneute Prüfung ist festgelegt. Wer diese fünf Punkte prüft und dazu die Ehrlichkeit der Konsequenzen, erkennt die meisten schwachen Records.
Anti-Patterns
ADRs scheitern auf erkennbare Weise. Zimmermann hat 2023 mehrere solche Muster mit einprägsamen Namen katalogisiert, und die schädlichsten sollte man kennen.
Das Entscheidungsprotokoll als Index
Einzelne Records sind nützlich; das Protokoll als Ganzes ist nützlicher. Eine kurze Indexdatei (oft die README.md des Entscheidungsordners) führt jeden Record mit Nummer, Titel, Status und Datum auf. Wer neu ist, liest sie in fünf Minuten und erhält eine komprimierte Geschichte der Architektur: was entschieden, was verworfen, was ersetzt wurde und wann. Werkzeuge wie adr-tools können den Index erzeugen und ablösende Records anlegen, die den Status des alten Records automatisch aktualisieren, und Dokumentationswerkzeuge wie die Structurizr DSL können einen Ordner mit ADRs in die veröffentlichte Dokumentation importieren.
Behandeln Sie das Protokoll als Teil der Architekturbeschreibung. Die arc42-Vorlage hat einen Abschnitt für Architekturentscheidungen, der einfach darauf verlinken kann, und eine Docs-as-Code-Pipeline kann es zusammen mit der übrigen Dokumentation veröffentlichen.
# Decision log
| ADR | Title | Status | Date |
|------|------------------------------------------------------|------------------------|------------|
| 0001 | Record architecture decisions | Accepted | 2025-03-02 |
| 0004 | Use the payment provider's hosted card fields | Accepted | 2025-04-18 |
| 0007 | Use managed PostgreSQL for the order service | Accepted | 2025-06-11 |
| 0009 | Send push notifications through a third-party SDK | Superseded by 0015 | 2025-09-30 |
| 0012 | Publish order events through a managed broker | Accepted | 2026-09-14 |
| 0013 | Store courier locations in a time-series database | Rejected | 2026-09-20 |
| 0015 | Run our own notification service on the broker | Accepted | 2026-10-08 |
Prüfen Sie Ihr Verständnis
Warum sollte der Abschnitt „Kontext“ eines ADR nicht für die gewählte Option argumentieren?
Weil seine Aufgabe darin besteht, die Kräfte und Fakten so festzuhalten, wie sie waren, damit spätere Lesende beurteilen können, ob sie noch gelten. Ist der Kontext als Plädoyer geschrieben, kann man die Situation nicht von der Schlussfolgerung trennen.
Ihr Team ändert seine Meinung zu einer akzeptierten Entscheidung. Was machen Sie mit dem alten ADR?
Seinen Inhalt unverändert lassen, seinen Status mit einem Link auf den neuen Record auf „abgelöst“ setzen und ein neues ADR schreiben, das erklärt, was sich am Kontext geändert hat und was nun entschieden ist.
Was ergänzt der MADR-Abschnitt „Confirmation“, das Nygards Format fehlt?
Eine Aussage darüber, wie das Team prüfen wird, ob die Entscheidung umgesetzt ist und weiterhin gilt, etwa durch einen Lasttest, ein Review oder eine automatisierte Prüfung der Abhängigkeiten.
Woran lässt sich schnell prüfen, ob ein ADR wirklich Alternativen und Kosten betrachtet hat?
Versuchen Sie, es als Y-Statement zu schreiben. Lassen sich die Teile „und gegen“ oder „und nehmen in Kauf, dass“ nicht ehrlich füllen, fehlen dem Record echte Optionen oder echte Konsequenzen.
Quellen und weiterführende Literatur
Haben Sie eine Frage zu diesem Abschnitt? ArchitectBot, der KI-Lernassistent des Kurses, antwortet zuerst aus dem Kurs.
Fragen: „Wir haben ein zwei Jahre altes System und keine ADRs. Sollten wir Records für die bereits getroffenen Entscheidungen schreiben, und wenn ja, wie vermeiden wir nachträgliche Rechtfertigungen?“