Let's use the classic example of blog context. In our domain we have the following scenarios: Users
can write Posts
. Posts
must be cataloged at least in one Category
. Posts
can be described using Tags
. Users
can comment on Posts
.
The four entities (Post
, Category
, Tag
, Comment
) are implemented as different aggregates because of I have not detected any rule for that an entity data should interfere in another. So, for each aggregate I will have one repository that represent it. Too, each aggregate reference others by his id.
Following CQRS, from this scenario I have deducted typical use cases that result on commands such as WriteNewPostCommand
, PublishPostCommand
, DeletePostCommand
etc... along with their respective queries to get data from repositories. FindPostByIdQuery
, FindTagByTagNameQuery
, FindPostsByAuthorIdQuery
etc...
Depending on which site of the app we are (backend or fronted) we will have queries more or less complex. So, if we are on the front page maybe we need build some widgets to get last comments, latest post of a category, etc... Queries that involve a simple Query
object (few search criterias) and a QueryHandler
very simple (a single repository as dependency on the handler class)
But in other places this queries can be more complex. In an admin panel we require to show in a table a relation that satisfy a complex search criteria. Might be interesting search posts by: author name (no id), categories names, tags name, publish date... Criterias that belongs to different aggregates and different repositories.
In addition, in our table of post we dont want to show the post along with author ID, or categories ID. We need to show all information (name user, avatar, category name, category icon etc).
My questions are:
At infrastructure layer, when we design repositories, the search methods (findAll, findById, findByCriterias...), should have return the corresponding entity referencing to all associations id's? I mean, If a have a method
findPostById(uuid)
orfindPostByCustomFilter(filter)
, should return a post instance with a reference to all categories id it has, all tags id, and author id that it has? Or should my repo have some kind of method that populates a given post instance with the associations I want?If I want to search posts created from 12/12/2014, written by John, and categorised on "News" and "Videos" categories and tags "sci-fi" and "adventure", and get the full details of each aggregate, how should create my
Query
andQueryHandler
?
a) Create a Query
with all my parameters (authorName, categoriesNames, TagsNames, if a want retrive User
, Category
, Tag
association full detailed) and then his QueryHandler
ensamble the different read models in a only one. Or...
b) Create different Queries
(FindCategoryByName, FindTagByName, FindUserByName) and then my web controller calls them for later
call to FindPostQuery but now passing him the authorid, categoryid, tagid returned from the other queries?
The b) solution appear more clean but it seems me more expensive.