I'm building a system that automates operations against an external service. There are two kinds of code fighting for the same space, and I can't find the clean boundary between them.
On one side I have a clean primitive interface — a set of dumb, direct verbs. "Do this one action against the service and tell me what happened." I like these clean and minimal. One of these verbs is, say, "register a user."
On the other side I want a smart, black-box system — the kind of thing where I call one method (createUser()) and it magically handles everything behind the scenes: which network egress/identity to send through, retries with backoff, atomic claiming of shared resources, idempotency and crash-recovery, doing outstanding work only. I want to be able to "Laravel my way" with it — express intent, let the machinery handle the rest.
The difficulty is that introducing all this efficiency/resilience machinery changes the layout of the code. It's no longer obvious where things go. The smart layer wants to know about the same actions the clean primitives expose, so I feel like I'm defining "register a user" in two places and it smells like duplication or confusion. The optimization mechanisms (multi-mechanism resource handling, tiered routing, retry logic) bleed into decisions about how to structure everything, and they make the structural choices harder, not easier.
Concretely: I have a clean request object that can already "register." But I also want a system-wide orchestration that does the magic version of creating a user. Where does that live? How do I keep the clean interface clean while also having the smart system, without the two collapsing into each other or duplicating responsibility? Every "which class should own this" decision feels 50/50 and heavy, because the efficiency machinery touches everything.
How do you think about structuring this?

Comments
Nothing yet. Say the first thing.
Sign in to join the conversation.