What's the difference between 'strict' layering (each layer may only call the layer immediately below it) and 'relaxed' or 'open' layering (a layer may call any layer below it, not just the adjacent one), and what does each cost you?
answer
- adjacent-only vs any-below
- pass-through boilerplate
- sinkhole layers
- reads bypass, writes don't
- guardrail via arch tests
basics
~20 sStrict layering: each layer can only call the layer directly beneath it. Relaxed/open layering: a layer may call any lower layer, skipping ones in between. Strict is safer but more boilerplate; relaxed is faster but easier to tangle.
solid answer
~50 sIn strict layering, layer N may only depend on layer N-1; if the presentation layer needs something from the data layer, it must go through the business layer, even if that means writing pass-through code. In relaxed (open) layering, a layer may call any layer below it directly - e.g., a controller calling a repository directly for a simple read, bypassing the service layer. Strict layering maximizes substitutability and enforces that all business rules pass through the business layer, but generates pass-through boilerplate for simple operations. Relaxed layering cuts that boilerplate and often improves performance by removing hops, but weakens the guarantee that business rules are centrally enforced - it's easy for validation or authorization logic to get bypassed when reads go straight to the data layer, and it's harder to reason about which layers a given change actually touches.
go deeper
Should be able to state that strict means 'only talk to the layer right below you' and relaxed means 'can skip layers', with a simple example of each.
Should articulate the concrete cost of each - boilerplate for strict, inconsistent enforcement risk for relaxed - and give an example of a cross-cutting concern (auth, logging) that strict layering protects.
Should describe how to scope relaxed layering safely (reads-only, single-entity, written convention) and mention enforcing it with automated architecture tests rather than review discipline alone.
Should connect the choice to system-level risk tolerance and team maturity - e.g., choosing strict layering deliberately in a regulated/audited domain because the enforcement guarantee is worth the boilerplate cost, versus relaxed layering in a fast-moving internal tool where the risk is acceptable.
## The two rules Strict layering and relaxed (also called 'open') layering describe how tightly the downward dependency rule from adjacent layers is enforced. | Style | The rule | What it means in practice | |---|---|---| | **Strict layering** | layer N is allowed to call only layer N-1, full stop | if the presentation layer needs a value that ultimately lives in the database, it must ask the business layer, which asks the data layer; there is no shortcut, even for a trivial read like 'fetch a user's display name.' | | **Relaxed/open layering** | a layer may call any layer below it, not just the adjacent one | a controller can call a repository directly for a simple lookup, skipping the service layer entirely, while writes and anything involving business rules still go through the full stack | ## Why teams relax the rule The motivation for relaxing the rule is almost always the same: strict layering, applied uniformly, generates **pure pass-through code**. If the business layer's only job for a given operation is to call the exact matching method on the repository and hand the result straight back with no transformation or rule applied, that service method adds a stack frame and a file to maintain without adding any actual logic. Multiplied across dozens of simple read operations in a large system, this becomes real maintenance drag. Relaxed layering lets those read paths shortcut directly to the data layer, keeping the service layer reserved for operations that actually carry business rules: - validation; - orchestration across multiple repositories; - authorization checks; - transactional boundaries. ## The trade-off The trade-off is genuine on both sides, not a strict improvement. - **Strict layering's cost** is the pass-through boilerplate just described, plus extra latency from additional method calls and mapping. **Its benefit** is a strong, uniform guarantee: every request, read or write, passes through the business layer, so if you centralize a cross-cutting concern there — authorization, auditing, caching, rate limiting — you know it fires every time, because there is no other path to the data. - **Relaxed layering's benefit** is less code and fewer hops for the common case; **its cost** is that the guarantee disappears. Nothing stops someone from adding a bypass path for an operation that, six months later, turns out to need an authorization check after all, while several other read paths already went straight to the data layer without one. ## The failure mode in production The concrete failure mode in production is **inconsistent enforcement of cross-cutting concerns**. Say a system centralizes row-level access control in its service layer — a user can only read orders they own — and a new engineer, following the relaxed-layering convention used elsewhere for 'simple reads,' adds a controller endpoint that queries the repository directly for an admin order list. If that endpoint is later exposed to non-admin users, or a permission change lands only in the service layer's check, the direct-to-repository endpoint silently keeps returning unauthorized data, because it was never in the code path that got fixed. This is exactly the kind of bug that's invisible in a code review of the endpoint alone. ## Keeping the exception narrow Teams that use relaxed layering successfully make the exception explicit and narrow rather than ad hoc: - **a written convention** such as 'GET-only read paths may call the repository directly if and only if no filtering/authorization beyond ownership-by-id is required; all writes and list/search operations must go through the service layer,' - **backed by an architecture test** (an ArchUnit-style rule, or a custom static check) that fails the build if a controller imports a repository outside the whitelisted read methods. Without that kind of guardrail, relaxed layering tends to drift over time into something closer to no layering at all, since 'just call the repository directly, it's simpler' is always locally true in the moment a new endpoint is written. ## Where the tension is written up A well-known real-world articulation of this exact tension is Martin Fowler's discussion of layering in 'Patterns of Enterprise Application Architecture' and his later bliki notes, where he explicitly contrasts strict layering with relaxed/open layering and names the failure mode of forcing every trivial pass-through through every layer as producing **'sinkhole' layers** — ones that add no value on a given call path and exist purely to satisfy the strict rule.
- If a team adopts relaxed layering for reads, how do they stop it from silently becoming relaxed layering for writes too?By making the exception explicit in writing - e.g., 'controllers may call repositories directly only for single-entity GET-by-id reads; every write and every multi-entity query must go through the service layer' - and enforcing it with an automated architecture test rather than relying on code review discipline alone. Without an automated check, the boundary tends to erode because each individual shortcut looks harmless in isolation.
- Does relaxed layering mean the layers no longer provide any decoupling benefit?No - the layers still exist as separable units for the operations that go through them, and the data layer can still be swapped or mocked for testing the service layer's business logic. What's lost is the universal guarantee that every request path passes through the business layer, so any cross-cutting concern that lives only there is only guaranteed for paths that actually route through it.
- Is relaxed layering the same thing as having no architectural layers at all?No. Relaxed layering still respects the downward dependency direction - a controller can call a repository directly, but a repository still can't call back up into a controller, and the layers still have distinct responsibilities. Having no layering at all would mean no consistent rule about who can depend on whom, closer to a big ball of mud.
Strict layering is like a strict corporate expense approval chain where every request, no matter how small, must go through your manager, then their manager, then finance - nothing skips a step. Relaxed layering is like letting employees submit small expenses (a $5 coffee) straight to finance while anything over $500 still needs the full manager chain - faster for the common case, but only safe if everyone agrees exactly where the line is.
saying these in an interview costs you the question
- Claims relaxed layering means any layer can call any other layer including upward
- Can't name a concrete cost of strict layering (pass-through boilerplate) or a concrete risk of relaxed layering (bypassed cross-cutting concerns)
- Thinks the choice is all-or-nothing rather than scoped per operation type (reads vs writes)
- Has no answer for how to keep a relaxed-layering exception from spreading uncontrolled