Repository
A repository hides storage mechanics while preserving the aggregate identity and consistency boundary.
- RepositoryLoads and stores domain aggregates by their identity.
- AggregateProtects its invariants within the consistency boundary.
- AdapterTranslates the contract into concrete storage operations.
Context
Why this is important
Design a repository as a domain-facing gateway to stored aggregates and distinguish it from table access.
Loading and saving aggregates through a suitable domain contract.
Repository contract and table access
The Ordering module owns order data; Stock manages its reservations within the same modular monolith.
This is how you read the picture
- Repository Storage contract
- Aggregate Consistency boundary
- Adapter Technology boundary
| Criterion | Aspect | Repository |
|---|---|---|
| Responsibility | Store aggregate | Load aggregate |
| Limit | Business identity | Storage technology |
Benefits & limitations
Helps if:
- A domain aggregate is loaded by its identity and stored after valid state changes.
- Callers should be able to replace the storage adapter while the repository contract expresses domain aggregates and queries.
Boundaries
- For simple CRUD applications, an additional repository contract may add little domain value over direct data access.
- A repository protects neither aggregate invariants nor a transaction across multiple aggregates; those responsibilities belong to the model and transaction boundary.
In practice
- Define which business identity the repository loads and stores, and limit its contract to those aggregates.
- Let the aggregate enforce its invariants when loaded and changed. Hide database queries, but keep business decisions out of the repository.
- Check the application with a storage adapter and test persistence-independent domain rules separately. Avoid repositories for every table row.
Read the detailed explanation
The contract typically supports lookup by business identity and saving changed aggregates. The concrete database, query language and mapping belong in the adapter.
A repository is not the consistency boundary. The aggregate root checks invariants; multiple aggregates do not become one transaction. One repository per table often obscures the domain model.
The repository loads and stores the Aggregate; its root protects business invariants.
A Factory creates the aggregate; the repository encapsulates storage access.
Check your understanding
Test yourself in three stages
ReadingCheck in the picture
What does the order repository load?
View the solution with justification
The order aggregate by its identity.
ApplyingTransferred to a new situation
Where do you check whether the order status may change?
View the solution with justification
In the aggregate that protects its invariants.
EvaluateWeighing an alternative
When does a repository become a technical table DAO?
View the solution with justification
When its contract exposes storage rows instead of business aggregates.
Explore further
These building blocks continue the thoughts of this page.
References
- Eric Evans · DDD Reference (opens in new tab)Primary reference for repository and factory patterns.
- DDD Reference · German translation (opens in new tab)German edition of Eric Evans’ reference.
- Vaughn Vernon · Implementing Domain-Driven Design (opens in new tab)Further treatment of tactical DDD building blocks and examples.