Boundary Definition
Boundaries are the most important architectural concept in Plumego.
Plumego itself is not complex.
What becomes complex — and dangerous — is allowing framework concerns to leak into places where they do not belong.
This document explains how to define and protect boundaries in a Plumego-based system.
What Is a Boundary?
A boundary is a point of translation.
At a boundary:
- One set of concepts ends
- Another set of concepts begins
- Data is transformed
- Responsibility changes hands
In Plumego, the most critical boundary is between:
HTTP / Framework concerns and Application / Domain concerns
The Primary Boundary: Handler → Application
The handler layer is the hard boundary between:
- Transport-specific concerns (HTTP)
- Transport-agnostic application logic
This boundary must be explicit and enforced.
Handler side (allowed)
Handlers may deal with:
- HTTP methods
- Status codes
- Headers
- Query parameters
- Request bodies
*plumego.Context
Application side (forbidden)
Application and domain code must not depend on:
*plumego.Contexthttp.Request- HTTP status codes
- Framework-specific helpers
If these appear outside the HTTP layer, the boundary has been violated.
Boundary as a Translation Layer
A good boundary translates, it does not forward blindly.
Instead of:
usecase.Execute(ctx)
Prefer:
input := CreateOrderInput{
UserID: ctx.UserID(),
Items: parseItems(ctx),
}
result, err := usecase.Execute(input)
The boundary performs:
- Data extraction
- Validation (where appropriate)
- Type conversion
This isolates inner layers from transport concerns.
Where Context Must Stop
*plumego.Context must stop at the HTTP boundary.
Passing context inward:
- Couples domain logic to HTTP
- Makes testing harder
- Prevents reuse across transports
- Leaks framework semantics
Correct usage
- Extract required values
- Pass primitive types or domain objects
- Pass
context.Contextonly if cancellation is required
Even then, prefer passing the embedded standard context, not the Plumego wrapper.
Boundary Between Application and Domain
The next boundary lies between:
- Application logic (use cases)
- Domain logic (core rules)
This boundary is more subtle but equally important.
Application layer responsibilities
- Orchestrate workflows
- Coordinate multiple domain objects
- Handle use-case-level rules
Domain layer responsibilities
- Enforce invariants
- Model core concepts
- Remain stable and isolated
The domain layer must not know:
- Which use case invoked it
- How the request arrived
- Which framework is used
Infrastructure Boundaries
Infrastructure sits outside the application core.
This includes:
- Databases
- External APIs
- Message queues
- Cache systems
Infrastructure should:
- Implement interfaces defined inward
- Be replaceable
- Contain volatile details
Application and domain layers should depend on abstractions, not implementations.
Boundary Enforcement Techniques
Plumego does not enforce boundaries automatically.
Teams must enforce them deliberately.
Common techniques include:
Package boundaries
- Use
internal/to restrict access - Separate HTTP, app, domain, infra packages clearly
Type boundaries
- Avoid exporting framework-specific types inward
- Define explicit input/output structs
Review discipline
- Treat boundary violations as architectural bugs
- Enforce rules consistently in code review
Boundaries are social contracts as much as technical ones.
Warning Signs of Boundary Erosion
Watch for these red flags:
- Domain code importing Plumego
- Use cases returning HTTP status codes
- Handlers containing business terminology
- Context passed deep into the call stack
- Infrastructure driving domain structure
These indicate boundaries are being crossed unintentionally.
Boundaries and Change Tolerance
Well-defined boundaries allow change without collapse.
Examples:
- Switching from HTTP to RPC
- Replacing a database
- Adding a new interface (CLI, worker)
- Refactoring business rules
Without boundaries, each change ripples unpredictably.
Plumego’s Role in Boundary Definition
Plumego helps by:
- Keeping the framework surface small
- Making boundaries visible
- Avoiding implicit coupling mechanisms
But Plumego will not save you from poor boundary discipline.
That responsibility belongs to the engineering team.
Summary
In a Plumego system:
- Boundaries define responsibility
- Translation happens at the edges
- Framework code stays outside the core
- Domain logic remains isolated and stable
Strong boundaries are the difference between a system that evolves
and one that collapses under its own weight.
Next
With boundaries defined, the next architectural concern is:
This explains how to structure application behavior without coupling it to Plumego.