Testable product workflows outside controllers
Backend architecture
TL;DR
- Controllers were not the right home for product workflows with real rules.
- I needed workflows to be easier to name, test, and change outside the HTTP layer.
- I moved billing, publishing, imports, search, and asset work into focused actions.
- The result was thinner controllers and clearer ownership for behaviour that mattered.
Controllers are a poor home for product workflows once the workflow has real rules. They know too much about HTTP and not enough about the work itself.
Where it started
As workflows grew, controller methods risked becoming a mix of HTTP handling, domain coordination, and side effects.
What needed to change
Action classes give each workflow a focused place to live. Billing changes, publishing steps, imports, search indexing, and asset operations can each be tested without routing through a full controller.
What I built
Controllers receive requests and delegate to actions. Actions coordinate validation, domain objects, side effects, and return values.
The HTTP layer stays thin, and the product workflow becomes easier to name.
What changed
This makes behaviour easier to test and easier to change. It also helps engineers find the real owner of a workflow.
What I would watch
Actions need clear boundaries. If every helper becomes an action, the architecture becomes noisier without becoming clearer.
