Layering
Layering is not about adding more folders.
Layering is about defining responsibility and controlling dependency direction.
Plumego does not enforce a specific architectural style (such as Clean Architecture or DDD),
but it strongly encourages a layered structure with explicit boundaries.
This document explains the layering model Plumego is designed to support.
Why Layering Matters in Plumego
Plumego deliberately keeps the framework thin and constrained.
As a result:
- Plumego will not protect you from architectural drift
- Poor structure will surface quickly
- Good structure will pay off for years
Layering is the primary tool for managing complexity in long-lived Plumego systems.
The Core Principle: Dependency Direction
The most important rule is simple:
Dependencies must point inward, never outward.
This means:
- Inner layers must not depend on outer layers
- Framework code must not leak into domain logic
- Transport details must remain at the edges
Everything else follows from this rule.
The Recommended Layer Model
A typical Plumego application can be structured into the following layers:
βββββββββββββββββββββββββββββββ
β HTTP Layer β β Plumego
β (Router, Middleware, β
β Handlers) β
βββββββββββββββ¬ββββββββββββββββ
β
βββββββββββββββΌββββββββββββββββ
β Application Layer β
β (Use cases, services) β
βββββββββββββββ¬ββββββββββββββββ
β
βββββββββββββββΌββββββββββββββββ
β Domain Layer β
β (Entities, core rules) β
βββββββββββββββ¬ββββββββββββββββ
β
βββββββββββββββΌββββββββββββββββ
β Infrastructure Layer β
β (DB, cache, external) β
βββββββββββββββββββββββββββββββ
Not every project needs all layers on day one.
But the direction of dependencies must remain consistent.
HTTP Layer: The Boundary Layer
The HTTP layer includes:
- Router
- Middleware
- Handlers
- Request/response formatting
Responsibilities:
- Translate HTTP requests into application calls
- Translate application results into HTTP responses
- Handle protocol-level concerns only
Rules:
- May depend on Application layer
- Must not contain business logic
- Must not be depended on by inner layers
This layer is where Plumego lives.
Application Layer: Use Cases and Coordination
The application layer coordinates behavior.
It contains:
- Use cases
- Application services
- Workflow orchestration
Responsibilities:
- Express what the system can do
- Coordinate domain objects
- Enforce application-level rules
Rules:
- May depend on Domain layer
- Must not depend on HTTP or Plumego
- Should be testable without HTTP
This layer represents system behavior, not protocol.
Domain Layer: Core Business Rules
The domain layer is the heart of the system.
It contains:
- Entities
- Value objects
- Domain rules
- Domain errors
Responsibilities:
- Represent core business concepts
- Enforce invariants
- Remain stable over time
Rules:
- Must not depend on Plumego
- Must not depend on HTTP
- Must not depend on infrastructure details
If a rule changes often, it probably does not belong here.
Infrastructure Layer: Implementation Details
The infrastructure layer contains:
- Database implementations
- Cache clients
- External service adapters
- Message brokers
Responsibilities:
- Implement interfaces defined by inner layers
- Handle IO and side effects
Rules:
- Depends inward (Application / Domain)
- Should be replaceable
- Must not define business rules
Infrastructure is where volatility is expected.
A Concrete Directory Example
A simple Plumego project might evolve into:
internal/
βββ http/
β βββ handler/
β βββ middleware/
βββ app/
β βββ usecase/
βββ domain/
β βββ user/
β βββ order/
βββ infra/
βββ mysql/
βββ redis/
This is only one possible layout.
The important part is not the names β
it is who depends on whom.
What Plumego Does Not Enforce
Plumego does not enforce:
- A specific folder structure
- A specific naming convention
- A specific architectural pattern
It provides a framework edge that fits naturally into layered designs.
Discipline must come from the team.
Common Layering Mistakes
Letting HTTP Types Leak Inward
Avoid passing *plumego.Context into application or domain code.
This couples core logic to transport details.
Putting Business Logic in Handlers
Handlers should translate, not decide.
Business rules belong inward.
Making Infrastructure the Center
Database schemas and external APIs should not define your systemβs structure.
They are implementation details, not the model.
Layering and Long-Term Evolution
Good layering enables:
- Changing frameworks without rewriting core logic
- Supporting multiple transports (HTTP, RPC, CLI)
- Incremental refactoring instead of rewrites
This is the primary reason Plumego emphasizes boundaries.
Summary
Plumego encourages a layered architecture where:
- Responsibilities are clear
- Dependencies flow inward
- Framework code stays at the edges
- Core logic remains independent and stable
Layering is not optional for long-lived systems β
it is the foundation of maintainability.
Next
With layering established, the next architectural concern is:
β Boundary Definition
This explains how to draw and protect boundaries between layers in practice.