Suppose I am developing a RSS system (following DDD practises). Users have accounts. Accounts have feeds. Feeds have articles. Account, Feed and Article are my aggregate roots as well as ArticleAccountMeta (an aggregate that contains information whether an account has already read an article).

I decided to go without separate repository model (Hibernate entities), so my aggregate roots are also my ORM entities (for several reasons, not important for the question).

Now let's say a user (account) wants to see all his feeds with their articles. So the server needs to produce a list of feeds with their articles. Alongside each article, I need the ArticleAccountMeta object to indicate whether the user/account has already read the article. Naturally, I would create a few more "view" classes. These would be returned by a domain service (as the building process is more complicated and contains business logic) and they would directly reference the domain aggregate roots.

My first question is - is it okay to have these view classes in the domain "layer" despite only being a different representation of the already created aggregate roots? Should I call them view models or are they true aggregate roots that are only used for reading?

My second question is - when building DTOs without any additional business logic, is it okay to bypass creating a domain service and use a repository directly?

My third question is - in the domain layer, I don't know how the view classes will be used, thus I should not instruct repositories to fetch specific references eagerly. However, I need to do that to prevent the N+1 problem. What is the correct solution here?

Be aware: what comes next is a list of dangerous statements that I call my opinion.

First of all, I understand your reasons to use the same classes for your aggregates and your ORM entities but is my duty to tell you that doing so, you are incrementing the coupling between your policies (domain) and your details (ORM, DB).

Now, I will try to answer your questions:

My first question is - is it okay to have these view classes in the domain "layer" despite only being a different representation of the already created aggregate roots? Should I call them view models or are they true aggregate roots that are only used for reading?

I haven't got all the information but I would say that, if this "view" class is only used when the user is doing a read operation (I mean a GET request here) then this class is probably just a part of of your DTOs. If you constantly need this class in a modifying operation, then I would review the design, maybe there is a failure there.

My second question is - when building DTOs without any additional business logic, is it okay to bypass creating a domain service and use a repository directly?

I have seen how different organizations apply the two options here. I'm not worried about it, but I suggest you to separate your services that modify the state from the services that are just used to answer a query. Also, wether you decide to bypass the service or not, please be consistent across the application.

My third question is - in the domain layer, I don't know how the view classes will be used, thus I should not instruct repositories to fetch specific references eagerly. However, I need to do that to prevent the N+1 problem. What is the correct solution here?

How would it be if you separate your aggregates from your ORM entities? I don't know which technology are you using but in that case I think you would need to fetch the entities eagerly. That's why I use to design my aggregates thinking in scale. I think that in your aggregate roots you should have a list of other aggregate roots/entities only if you know that the number of them will be really small. Otherwise, I would remove that list and add the reference in the other side of the relation.

There are a lots of topics in this discussion so please let me know if I helped you or what else do you need to know :)

  • The first question is still unclear, however. The "DTO" is used only for reading, however as building it requires business logic, I assume it should be in the domain. However, the "DTO" and aggregate roots it is built of share some common data. Is that OK? Apart from that, everything clear. Thank you. – Juraj Mlich Dec 4 at 20:44
  • Ok, I understand now. You probably need to design it as a Value Object (inside your domain). It is not an entity so you don't need an ID for it and also, remember that it should be immutable. This makes sense to you? Please mark the answer as accepted if you think I solved your doubts :) – Ariel Kohan Dec 5 at 10:26

From what I've seen:

Entity layer has entity objects that then transfer into POCO objects (these are your domain classes) and then into DTOs for presentation.

I also believe

so my aggregate roots are also my ORM entities

Isn't going to scale in the slightest as you're already starting to see, so I'd use the dedicated entity objects and then automapper them over to true domain objects and then optionally a DTO.

  • Yea, I know that is a way to go, but the application will not be complicated enough so that this would pay off. That is why I am trying to find the best solution without this. – Juraj Mlich Nov 29 at 6:21

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.