Skip to main content
Development

Your architecture decisions vanish. ADRs fix that.

A decision made without a written trace is a context debt. Architecture Decision Records are the most useful document nobody writes until it costs you.

ADR Architecture Documentation Symfony Migration

The day nobody knows why

Classic scenario. You join a Symfony project. Inside src/Services/, a service called ApiClientService extends \GuzzleHttp\Client. But the project also uses symfony/http-client in three other places, added during a recent update.

You ask in Slack. Nobody knows. The person who made that call left the team in 2022. There might be a Jira thread — nowhere to be found. There might have been a meeting — no notes.

Result: you maintain two HTTP clients in the same application. You do not know if this is intentional or an oversight. You do not touch Guzzle. The debt accumulates.

This is not a code problem. This is a collective memory problem.

According to the Stack Overflow Developer Survey 2023, 42% of developers spend more than 30 minutes per week understanding undocumented code. Multiply by the team. Multiply by the year. The cost of forgetting is real, recurring, and avoidable.

What an ADR is — in 3 sentences

An Architecture Decision Record (ADR) is a short document that captures a significant architectural decision, along with its context and its consequences.

It is not a wiki. It is not a functional spec. It is a written trace of the reasoning: why this choice, at this point in time, with these specific constraints — and not another.

  • AD — the decision itself (Architecture Decision)
  • ADL — the full set of decisions accumulated over the project's life (Architecture Decision Log)
  • ASR — the requirement that drove the decision (Architecturally Significant Requirement)

The Nygard format: 3 sections, that is it

# ADR-0001 — Migrate from Guzzle to symfony/http-client

Date: 2026-03-12
Status: Accepted

## Context

Our Symfony 5 application uses GuzzleHTTP 6 for external API calls.
Migrating to Symfony 7 introduces symfony/http-client as a native component.
Maintaining two HTTP clients in the project increases the maintenance surface.

## Decision

Replace GuzzleHTTP with symfony/http-client during the Symfony 7 migration.
All services extending \GuzzleHttp\Client will be refactored.

## Consequences

- One fewer third-party dependency (Guzzle removed from composer.json)
- Native integration with the Symfony profiler (simpler HTTP request debugging)
- Refactoring required: 4 services identified (ApiClientService, WebhookService, etc.)
- ADR-0002 will address replacing Guzzle mocks in unit tests

When to write an ADR?

  • Third-party library choice
  • Database structure change
  • Security decision
  • Infrastructure choice
  • Deliberate rejection of an option

Practical rule: if reversing this decision would cost more than a day of work, it deserves an ADR.

The solo developer — and the Réunion context

I have maintained Symfony legacy projects in Réunion for 7 years. In this context, the developer who picks up the code in 18 months is often myself.

Your first ADR: 15 minutes, right now

mkdir -p adr
touch adr/0001-name-of-the-decision.md

Next in the series: how to organize your ADRs in a Git workflow, compare 3 formats, and integrate ADR review into your pull requests.

In the same vein