Skip to main content
Learn

Link Architecture Decision Records

โฑ 2 min read๐ŸŸก Intermediate ยท 30-45 minutesEdit on GitHub โ†—

Overviewโ€‹

Connect architectural decisions to your CALM architecture by linking Architecture Decision Records (ADRs).

Learning objectivesโ€‹

By the end of this tutorial, you will:

  • Understand how CALM's adrs property links decisions to architecture
  • Use the MADR format to write clear, structured ADRs
  • Link both local markdown files and external URLs as ADRs
  • Create an ADR index for your project

Prerequisitesโ€‹

Complete the Beginner Tutorials section first. You will need your architectures/ecommerce-platform.json from the Build a Complete Architecture lesson.

Step-by-Step Guideโ€‹

1. Understand ADRs in CALMโ€‹

Architecture Decision Records (ADRs) capture significant architectural decisions along with their context and consequences. CALM supports linking ADRs to architectures through the adrs top-level property.

How CALM ADR Linking Works:

  • The adrs property is a simple array of URL strings
  • URLs can be relative paths to local markdown files (e.g., docs/adr/0001-decision.md)
  • URLs can be absolute URLs to external resources (e.g., a wiki, GitHub repo, or ADR management tool)

ADR Format โ€” MADR: We'll use MADR (Markdown Any Decision Records) which includes:

  • Title and date
  • Status (Proposed, Accepted, Deprecated, Superseded)
  • Context (the situation and problem)
  • Decision (what was decided)
  • Consequences (positive and negative impacts)

Already have ADRs? If your organization maintains ADRs in a wiki or ADR tool, you can link directly to those URLs instead of creating local files.

2. Create Your ADR Directoryโ€‹

mkdir -p docs/adr

3. Create Your First ADRโ€‹

File: docs/adr/0001-use-message-queue-for-async-processing.md

Content:

# 1. Use Message Queue for Asynchronous Order Processing

Date: 2024-12-15

## Status
Accepted

## Context
Our e-commerce platform needs to handle order processing asynchronously to:
- Improve user experience with fast order confirmation
- Decouple order capture from payment processing
- Handle traffic spikes without overloading payment services
- Enable retry logic for failed payment attempts

## Decision
We will introduce a RabbitMQ message broker between the Order Service and Payment Service.

**Technical Details:**
- Protocol: AMQP
- Broker: RabbitMQ 3.12+
- Message format: JSON
- Durability: Persistent messages with acknowledgments

## Consequences

### Positive
- **Resilience:** Payment service failures don't block order submission
- **Scalability:** Can scale payment processing independently
- **User Experience:** Immediate order confirmation
- **Retries:** Failed payments can be retried automatically

### Negative
- **Complexity:** Adds another system component to manage
- **Eventual Consistency:** Order status updates are asynchronous
- **Operational Overhead:** Requires monitoring, backlog management

4. Create a Second ADRโ€‹

File: docs/adr/0002-use-oauth2-for-api-authentication.md

Content:

# 2. Use OAuth2 for API Authentication

Date: 2024-12-15

## Status
Accepted

## Context
The API Gateway requires a secure, standardized authentication mechanism for:
- Web application clients
- Mobile application clients
- Third-party API integrations

## Decision
Implement OAuth2 with JWT tokens for all API authentication.

**Technical Details:**
- Standard: OAuth 2.0 (RFC 6749)
- Token format: JWT (RFC 7519)
- Grant types: Authorization Code, Client Credentials
- Token expiry: 1 hour access tokens, 30 day refresh tokens

## Consequences

### Positive
- **Industry Standard:** Well-understood, widely supported
- **Flexibility:** Supports multiple client types
- **Stateless:** JWTs contain claims, no server-side session storage

### Negative
- **Token Management:** Clients must handle refresh logic
- **Revocation:** Immediate revocation requires additional infrastructure

Prompt:

Add an adrs array at the top level of architectures/ecommerce-platform.json (after the $schema and before metadata).

Add these URLs:
- "docs/adr/0001-use-message-queue-for-async-processing.md"
- "docs/adr/0002-use-oauth2-for-api-authentication.md"

These are relative paths from the repository root.

6. Validate with ADRsโ€‹

calm validate -a architectures/ecommerce-platform.json

Should pass! โœ…

7. Create an ADR Indexโ€‹

Create an index table listing each ADR, its title, and date. Link the ADRs in architectures/ecommerce-platform.json to keep traceability clear.

File: docs/adr/README.md

Content:

# Architecture Decision Records

This directory contains Architecture Decision Records (ADRs) for the e-commerce platform.

## Format

We use **MADR (Markdown Any Decision Records)** format, based on [the MADR template](https://adr.github.io/madr/):

- Title and date
- Status (Proposed, Accepted, Deprecated, Superseded)
- Context (the situation and problem)
- Decision (what was decided)
- Consequences (positive, negative, and mitigations)

## Linking to CALM

All ADRs in this directory are linked from `architectures/ecommerce-platform.json` in the `adrs` array. This creates traceability between decisions and implementation.

## Index

### Active

| ADR | Title | Date |
|-----|-------|------|
| [0001](0001-use-message-queue-for-async-processing.md) | Use Message Queue for Asynchronous Order Processing | 2024-12-15 |
| [0002](0002-use-oauth2-for-api-authentication.md) | Use OAuth2 for API Authentication | 2024-12-15 |

### Superseded
None yet.

## Creating New ADRs

Use the numbering sequence: 0003, 0004, etc.

Filename format: `NNNN-short-title-with-hyphens.md`

Link the ADR in `architectures/ecommerce-platform.json` in the `adrs` array.

## Benefits

1. **Traceability:** Link decisions to architecture implementation
2. **Onboarding:** New team members understand "why" not just "what"
3. **Auditing:** Decision history for compliance and reviews
4. **Evolution:** Track how architecture decisions change over time

Remember to baseline your work using git. Committing at this point gives you a clean restore point if you need to revisit this lesson.

Key conceptsโ€‹

The adrs Propertyโ€‹

{
"$schema": "https://calm.finos.org/release/1.2/meta/calm.json",
"adrs": [
"docs/adr/0001-use-message-queue-for-async-processing.md",
"docs/adr/0002-use-oauth2-for-api-authentication.md"
],
"nodes": [...]
}

The adrs array is a flat list of URL strings โ€” either relative local paths or absolute URLs to external ADR repositories.

MADR Template Structureโ€‹

SectionPurpose
TitleShort description of the decision
StatusCurrent state: Proposed / Accepted / Superseded
ContextThe situation that drove the decision
DecisionWhat was chosen and key technical details
ConsequencesPositive outcomes, negative trade-offs, mitigations

ADR Lifecycleโ€‹

  1. Proposed โ€” drafted, under review
  2. Accepted โ€” approved and in effect
  3. Superseded โ€” replaced by a newer ADR (link to the replacement)

Never edit an accepted ADR โ€” supersede it instead to preserve decision history.

Next stepsโ€‹

In the next tutorial, you'll generate a shareable documentation website from your architecture!