There seems to be a confusion between domain driven design concepts, API design and implementation approach.
Domain design concepts
First a few definitions of Evan's DDD reference book:
Aggregate: A cluster of associated objects that are treated as a unit for the purpose of data changes. External references are
restricted to one member of the aggregate, designated as the root.
Entity: An object fundamentally defined not by its attributes, but by a thread of continuity and identity.
And keep in mind that this is about the domain. We don't care here how the relationships between the objects will be implemented. Therefore, from what you say:
User
and related Posts
belong to the same aggregate, and User
is the root entity thereof. This says that whenever I want to refer to a Post
, however it is implemented, I have to access it via the User
.
- it's not clear if
Post
within the aggregate is an entity or a value object. The difference is about identity semantics: is a post that is updated (e.g. correction of a typo) still the same post or would if be considered as another post ? Personally I'd opt for the entity, but up to you to see what fits best your domain.
API design & implementation model
The domain model is independent of any specific implementation. But in order to implement it, you'll have to define:
- An API, that defines how the domain is exposed to the application layers that use the model (e.g. controllers and views).
- An implementation approach for managing the implementation dependent internals of the model, for example to ensure the persistence (e.g. use of an Object-Relational mapping or use of a NOSQL database).
The domain model shall not be a prison that imposes you to blindly do things that hamper performance, but a guide to structure better your software.
In your specific case, you could for example use lazy loading: your API may give the impression that everything is loaded at once with the User
, but in reality, the posts
will not be loaded until someone tries to access it via the User
(thanks to encapsulation).
But you could also define an API that seems to give direct access to the entities in the aggregate, but which enforce the access to Post
to go via User
, so that you have the opportunity to safeguard the consistency of the related objects.
You could also, as you suggest yourself, create different kind of User
objects in your application to determine what is to be loaded and what could be changed. But then it's an implementation model and no longer the conceptual domain model anymore.