When working with Domain-Driven Design creating well designed aggregates is one of the least well understood patterns, Vaughn Vernon explains in two articles giving some guidelines for composing aggregate boundaries and alternatives to an ORM when storing them.
Vaughn, author of Implementing Domain-Driven Design, defines four rules that he believes will simplify aggregate composition:
- Protect true invariants in consistency boundaries, which also imply that only one aggregate should be modified within a transaction.
- Design small aggregates, with a single entity the smallest possible.
- Reference other Aggregates only by identity, meaning you should not from one aggregate be able to directly access another aggregate.
- Use eventual consistency outside the consistency boundary. One way of doing this is to use domain events to inform other parts, which in turn can initiate a separate update of an aggregate within a new transaction.
Vaughn strongly recommends a start with the second rule, letting each entity without exception become an aggregate root, then adding all fields or attributes needed for the aggregate to be created into a valid state.
Vaughn’s next step is to work with domain experts to find the aggregates that must be updated within the same transaction, and those that can be updated as a reaction to other updates. Here Vaughn warns for domain experts claiming that all entities have to be updated in the same transaction. This is very unlikely and probably more due to experts with experience from working with databased centric systems.
Searching for a better way than using an Object-Relational Mapping (ORM) framework for storing aggregates Vaughn has looked into serializing aggregates as JSON, then storing these in a document database. When working with domain events they must be stored within the same transactions as the aggregate update, otherwise a system may end up being inconsistent due to storage failures. A problem when using document databases is that most of them don’t support ACID transactions, in practice making them unusable in system where inconsistency is not acceptable. Instead Vaughn has looked for a data storage that supports transactions as well as JSON and one example he has found is a beta release of PostgreSQL 9.4 which he has used in a small example creating an aggregate storage.
Vaughn has also written a three part series about Effective Aggregate Design.
Julie Lerman earlier wrote about sharing data between bounded contexts.