We Said Django Was an Adapter. Prove It.
Calling Django an adapter was an architectural claim. Replacing its HTTP role with Flask was the experiment.
For much of the project, I had been making an architectural claim:
Django was an adapter. It did not own the business.
The structure appeared to support that claim.
HTTP
↓
Django / DRF
↓
Application
↓
DomainBusiness rules lived in the Domain. Application operations were expressed through commands and handlers. Django REST Framework translated HTTP requests at the edge.
It looked right. But an architecture diagram is not proof. Neither is putting Django inside a directory named adapters.
So I decided to challenge the claim.
Change One Thing
Instead of rewriting the application with another stack, I changed one variable.
Django / DRF
↓
Application
↓
DomainFlask
↓
Application
↓
DomainBefore implementing the Flask path, I defined the success criterion:
Domain changes = 0
Application changes = 0If another HTTP framework forced changes into the business core, then the architecture was telling me something important.
Flask Was Allowed to Be Flask
I did not try to hide Flask behind a universal web-framework abstraction. Flask used Flask concepts:
Blueprint
routes
error handlers
test_client()Django continued using Django and DRF concepts. The interesting question was not whether framework-specific code existed.
Where did that code stop?
Both HTTP paths eventually had to converge on the same existing Application behavior.
Django ─┐
├─→ PlaceOrderCommand
Flask ──┘
↓
existing Application
↓
Domain No FlaskPlaceOrderCommand. No Flask-specific business rules. No second Domain model.
Then I Tested the Real Path
An adapter test alone was not enough. A mock could prove that Flask called the right handler while still hiding coupling deeper inside the system.
So the stronger experiment used the real path:
Flask
↓
real Application
↓
real Domain
↓
existing persistence
↓
RedisI ran the system test.
1 passed in 0.90sGREEN. Immediately.
And the success criteria remained:
Domain changes = 0
Application changes = 0That immediate GREEN was the interesting result. There was no business-core implementation to fix. The HTTP framework changed without forcing the center to follow it.
What It Proved — and What It Didn't
The result did not mean that Django had disappeared from the system.
Django ORM still participated in persistence. That was a different architectural role and therefore a different experiment.
For the place-order operation, the inbound HTTP framework could change without requiring changes to the Domain or Application.
That is a much more useful claim than saying that the entire application is framework-independent.
Architecture becomes more credible when the conclusion is no larger than the experiment supporting it.
The Lesson
Calling something an adapter is easy. Drawing the arrow is easy. Creating an interface is easy.
Can you replace the thing you claim is replaceable without the business core changing with it?
That experiment changed the way I think about architectural boundaries.
No architectural claim without proof.
CONTINUE THE ARCHITECTURE JOURNEY
The experiment is only part of the story.
This is one experiment from my book Building Software Around the Business — Not Around the Framework — Backend Architecture with Python, Django, and Flask.
In the book, I walk through the complete development path: the first Flask RED, the boundary decisions, error translation, the system-level proof, why Django remained in persistence, and what the experiment still could not prove.
Explore the backend architecture book →