When CQRS Earns Its Place — and When It Doesn't
I split reads from writes. I still did not introduce CQRS.
Different responsibilities can earn segregation without earning CQRS.
The First Split Wasn't CQRS
The Order detail view could continue using the existing Order. The collection needed a different representation.
getOrder()
→ Order
listOrders()
→ OrderSummary[]Adding the collection capability to the original OrderApi also caused unrelated consumers to change. That pressure earned narrower OrderReadApi and OrderWriteApi capabilities.
Read/write interface segregation had been earned. CQRS had not.
Then the Write Side Began to Diverge
Cancellation introduced a second real write intention.
Adding cancellation to a broader write contract would make placement-only consumers depend on behavior they did not need.
PlaceOrderApi
└── placeOrder()
CancelOrderApi
└── cancelOrder()The write side had earned narrower capabilities because its consumers were beginning to need different things.
Now CQRS Became a Legitimate Question
By this point, the architecture had accumulated several real forms of divergence.
different read representations
different read and write responsibilities
multiple write intentions
narrow write capabilities
different application flowsThat was enough to ask whether CQRS had become the smallest responsible design.
It was not enough to answer yes.
But What Problem Would CQRS Solve?
The Application was still understandable as a small set of ordinary use cases.
loadOrder()
listOrders()
placeOrder()
cancelOrder()The detail read still returned Order, and the command workflows still operated on that same frontend Order concept.
There was no demonstrated problem requiring separate command and query execution architectures.
What I Deliberately Did Not Add
CQRS could have introduced a much larger execution model. But none of these mechanisms solved a problem the implementation had demonstrated.
WHAT WE EARNED
WHAT WE DIDN'T EARN
Recognizing a familiar architectural shape was not enough reason to introduce the pattern.
Where the Architecture Stopped
The smallest responsible architecture remained:
simple Application functions
+
narrow consumer capabilities
+
composed adaptersThe architecture had changed where pressure required it and stopped where the existing design was still sufficient.
The Lesson
Different responsibilities can earn segregation without earning CQRS.
CONTINUE THE ARCHITECTURE JOURNEY
The substitution experiment is only part of the story.
This experiment comes from my book Building Software Around the Business — Not Around the Framework — Frontend Architecture with TypeScript, Angular, and React.
The book follows the architecture from the first frontend behavior through Domain and Application boundaries, state ownership, capability segregation, runtime composition, and the final REST-to-GraphQL substitution proof.
Explore the frontend architecture book →