I used CQRS pattern with DDD,
I have some queries written using Dapper.
before fetching data I need to checking some rules. my main question: this rules must be handle with Domain Model? (that Domain Model fetched from the Repository)?
for example:
I want to fetch all payments transactions of an specific "financial group", before fetching data, must be check that current user be one of members the "financial group". now this checking must be handle with my domain model ("financial group")?
then in my query handler(CQRS pattern) I must be inject my Repository for get domain model?
I thought must be load domain model just for the Commands? and for the Queries must not load domain model.
I'll first address an issue about you saying that you "must do" something because some pattern tells you to. The right question to ask here is "should I do it"? To answer that, you yourself must evaluate the pros and cons of the approach.
As you are using Dapper and doing all this on the query side, it would be difficult and unnecessary to use a repository tied to a specific aggregate root.
Based on my understanding of your model, it could be as simple as something like this:
Validate that the user performing the query is a member of a specific financial group (authorization, done in code)
If the user can have access to the specific financial group -> Perform a query with dapper, something like:
SELECT *
FROM PaymentTransactionsReadTable pt
WHERE pt.FinancialGroup = #FinancialGroupParameter
If no, return a non-authorized result, exception, etc.
Remember that the query you are performing with Dapper can span multiple aggregates, do joins, cross apply's, etc as it is in a sense your QUERY from CQRS.
Related
I've been getting acquainted with DDD and trying to understand the way Entities and Aggregate Roots interact.
Below is the example of the situation:
Let's say there is a user and he/she has multiple email addresses (can have up to 200 for the sake of example). Each email address has it's own identity and so does the user. And there is one to many relationship between users and their email.
From the above example I consider Users and Emails as two entities while Users is the aggregate root
DDD Rules that I came across:
Rule: Only aggregate root has access to the repository.
Question 1: Does it mean that I cannot have a separate database table/collection to store the emails separately? Meaning that the emails have to be embedded inside the user document.
Rule: Entities outside the aggregate can only access other entities in the aggregate via the aggregate root.
Question 2: Now considering I do split them up into two different tables/collection and link the emails by having a field in email called associatedUserId that holds the reference to the user that email belongs to. I can't directly have an API endpoint like /users/{userId}/emails and handle it directly in the EmailService.getEmailsByUserId(String userId)? If not how do I model this?
I am sorry if the question seems a bit too naive but I can't seem to figure it out.
Only aggregate root has access to the repository
Does it mean that I cannot have a separate database table/collection to store the emails separately? Meaning that the emails have to be embedded inside the user document.
It means that there should be a single lock to acquire if you are going to make any changes to any of the member entities of the aggregate. That certainly means that the data representation of the aggregate is stored in a single database; but you could of course distribute the information across multiple tables in that database.
Back in 2003, using relational databases as the book of record was common; one to many relationships would normally involve multiple tables all within the same database.
Entities outside the aggregate can only access other entities in the aggregate via the aggregate root.
I can't directly have an API endpoint like /users/{userId}/emails and handle it directly in the EmailService.getEmailsByUserId(String userId)?
Of course you can; you'll do that by first loading the root entity of the User aggregate, then invoking methods on that entity to get at the information that you need.
A perspective: Evans was taking a position against the idea that the application should be able to manipulate arbitrary entities in the domain model directly. Instead, the application should only be allowed to the "root" entities in the domain model. The restriction, in effect, means that the application doesn't really need to understand the constraints that are shared by multiple entities.
Four or five years later cqrs appeared, further refining this idea -- it turns out that in read-only use cases, the domain model doesn't necessarily contribute very much; you don't need to worry about the invariants if they have already been satisfied and you aren't changing anything.
In effect, this suggests that GET /users/{userId}/emails can just pull the data out of a read-only view, without necessarily involving the domain model at all. But POST /users/{userId}/emails needs to demonstrate the original care (meaning, we need to modify the data via the domain model)
does this mean that I need to first go to the UserRepo and pull out the user and then pull out the emails, can't I just make a EmailService talking to an Email Repo directly
In the original text by Evans, repositories give access to root entities, rather than arbitrary entities. So if "email" is a an entity within the "user aggregate", then it normally wouldn't have a repository of its own.
Furthermore, if you find yourself fighting against that idea, it may be a "code smell" trying to bring you to recognize that your aggregate boundaries are in the wrong place. If email and user are in different aggregates, then of course you would use different repositories to get at them.
The trick is to recognize that aggregate design is a reflection of how we lock our data for modification, not how we link our data for reporting.
After reading Eric Evans' DDD, I'm trying to apply it to the project I'm managing. There are some user specific query data and I'm not really sure of how to implement this in a DDD way.
For example, if a user queries notices, the application should tell the user wether each post is read or not. Normally in such situations, I would respond with data that looks like following:
{
"notices": [
{"content": "foo", "is_read": true},
{"content": "bar", "is_read": false}
]
}
Suppose there is Notice entity and Read entity that saves wether a User has read it. Also assume that there are so many users reading the notice that retrieving all users for the is_read is not a efficient way.
Since Read entity is never queried without Notice entity, I could put it inside a Notice aggregate. Then implement query function taking the requesting user as parameter.
Or I could separate NoticeRepository and ReadRepository, query notices and then join them in the application layer with reads queried with notice ids.
The first option seems that it is assuming an user querying the notices and corrupting the domain layer with application logics. On the other hand, the second option gives me a feeling that I'm implementing a simple feature in an unnecessarily complicated way. And I cannot really think of other options right now.. What could be the best practice for such a case?
I cannot really think of other options right now
I can see two possible issues that could be tripping you up.
First, your domain model may be missing an important concept. How do we know if a Bob read a particular notification or not? There may be some entity in the domain, perhaps an Acknowledgement, that captures Bob, and the document that he read, and perhaps other information interesting to this domain (which version of the document did he read? When? What channel? when? and so on).
Thus, the view that would produce would look something like the list of active notifications left joined to the acknowledgements from Bob.
The other thing that could cross you up is that trying to do joins "by hand", using repositories to fetch data, is a real drag. Furthermore, what people have come to realize in the years since the blue book was written, it may not be necessary. Because queries are safe, they don't change the underlying data -- and if the underlying data isn't going to change, we don't really need a domain model to protect a business invariant.
This need to go all in a Query Service,
The book of Eric Evans is good basis and it has evolved to more modern patterns now, for instance CQRS in the book of Vaughn Vernon, Implementing Domain Driven Design (IDDD).
Your query service would be responsible of displaying a list of notices, updating a read column for this user in a separate table.
You might have a look at some example of query services (written in java) here:
https://github.com/VaughnVernon/IDDD_Samples/blob/master/iddd_collaboration/src/main/java/com/saasovation/collaboration/application/forum/ForumQueryService.java
https://github.com/VaughnVernon/IDDD_Samples/blob/master/iddd_collaboration/src/main/java/com/saasovation/collaboration/application/forum/DiscussionQueryService.java
I wouldn't have a Read entity. Just Notice and User. In User you would have a list of Notice ids that the user has read (or viceversa, in Notice you would have a list of the User ids who have read the Notice).
Then , to query the info you need to show in the user interface, you have several alternatives, as Vaughn Vernon says in his book Implementing DDD (page 512):
DTOs
Mediator
Domain Payload Object
State Representations
Use Case optimal repository queries (closed to CQRS)
Data Transformers
I have seen lot of discussions regarding this topic but i couldn't get a convincing answer. The general advice is not to have repository inside a domain object. What about an aggregate root? Isnt it right to give the root the responsibility to manipulate the composed objects?
For example, i have a microservice which takes care of invoices. Invoice is an aggregate root which has the different products. There is no requirement for this service to give details about individual products. I have 2 tables, one to store invoice details and other to store products of those invoices. I have two repositories corresponding to the tables. I have injected product repository inside the invoice domain object. Is it wrong to do so?
I see some mistakes according to DDD principles in your question. Let me try to clarify some concepts to give you hand.
First, you mentioned you have an Aggregate Root which is Invoice, and then two different repositories. Having an Aggregate Root means that any change on the Entities that the Aggregate consists of should be performed via the Aggregate Root. Why? That's because you need to satisfy some business rule (invariant) that applies on the relation of those Entities. For instance, given the next business rule:
Winning auction bids must always be placed before the auction ends. If a winning bid is placed after an auction ends, the domain is in an invalid state because an invariant has been broken and the model has failed to correctly apply domain rules.
Here there is an aggregate consisting of Auction and Bids where the Auction is the Aggregate Root.
If you have a BidsRepository, you could easily do:
var newBid = new Bid(money);
BidsRepository->save(newBid);
And you were saving a Bid without passing the defined business rule. However, having the repository just for the Aggregate Root you are enforcing your design because you need to do something like:
var newBid = new Bid(money);
auction.placeBid(newBid);
auctionRepository.save(auction);
Therefore, you can check your invariant within the method placeBid and nobody can skip it if they want to place a new Bid. Afterwards you can save the info into as many tables as you want, that is an implementation detail.
Second, you said if it's wrong injecting the repository into a Domain class. Here a quick explanation:
The repository should depend on the object it returns, not the other way around. The reason for this is that your "domain object" (more on that later) can exist (and should be testable) without being loaded or saved (that is, having a dependency on a repository).
Basically your design says that in order to have an invoice, you need to provide a MySQL/Mongo/XXX instance connection which is an infrastructure detail. Your domain should not know anything about how it is persisted. Your domain knows about the behavior like in the scenario of the Auction and Bids.
These concepts just help you to create code easier to maintain as well as help you to apply best practices such as SRP (Single Responsibility Principle).
Yes, I think it is wrong.
Domain should match real business model and should not care how data is persisted. Even if data internally are stored in multiple tables, this should not affect domain objects in any way.
When you are loading aggregate root, you should load related entities as well in one go. For example, this can easily be achieved with Include keyword in Entity Framework if you are on .NET. By loading all the data you ensure that you have full representation of business entity at any given time and you don't have to query database anymore.
Any changes in related entities should be persisted together with aggregate root in one atomic operation (usually using transactions).
I'm novice in DDD and CQRS patters and I want to have your opinion how a domain entity can be validated.
I'm going to use the common example Order->OrderLine, where Order is the AR.
The validation of business rules in an Aggregate is through the AR for consistency matters.
How can I validate a business rule that need data outside the Aggregate of Order?
I'm using also CQRS approach and I think that using the ReadModel to get the data that I need to make the validation of my business rules is not a bad option...What do you think?
With my experience of CQRS I associate the ReadModel as being eventually consistent, and therefore I wouldn't be 100% confident in the ReadModel representing the current state of the system. This becomes more the case when you want to distribute and replicate your ReadModels.
I would only want to use the ReadModel to limit the number of invalid commands being sent to your application.
It sounds to me that you want to start thinking about Domain Services, which can be used to encapsulate domain logic that falls outside the boundary of a single aggregate/entity/value object.
As David points out here Implement Domain Services as Extension Methods for the repository, Jimmy Bogard has a definition http://lostechies.com/jimmybogard/2008/08/21/services-in-domain-driven-design/
Yes, use the read model for command validation. I call this "command context" - the current state of the world, based on which command may be valid or invalid. In CQRS, this current state of the world is represented in your read model. User is making decisions based on it, what commands should be issued.
You may also consider various ways to guide user decisions, so that he doesn't issue invalid commands (warn in advance if username in not unique, etc).
Background
Udi Dahan suggests a fetching strategy as a useful pattern to use for data access. I agree.
The concept is to make roles explicit. For example I have an Aggregate Root - Customer. I want customer in several parts of my application - a list of customers to select from, a view of the customer's details, and I want a button to deactivate a customer.
It seems Udi would suggest an interface for each of these roles. So I have ICustomerInList with very basic details, ICustomerDetail which includes the latest 10 products purchased, and IDeactivateCustomer which has a method to deactivate the customer. Each interface exposes just enough of my Customer Aggregate Root to get the job done in each situation. My Customer Aggregate Root implements all these interfaces.
Now I want to implement a fetching strategy for each of these roles. Each strategy can load a different amount of data into my Aggregate Root because it will be behind an interface exposing only the bits of information needed.
The general method to implement this part is to ask a Service Locator or some other style of dependency injection. This code will take the interface you are wanting, for example ICustomerInList, and find a fetching strategy to load it (IStrategyForFetching<ICustomerInList>). This strategy is implemented by a class that knows to only load a Customer with the bits of information needed for the ICustomerInList interface.
So far so good.
Question
What you pass to the Service Locator, or the IStrategyForFetching<ICustomerInList>. All of the examples I see are only selecting one object by a known id. This case is easy, the calling code passes this id through and will get back the specific interface.
What if I want to search? Or I want page 2 of the list of customers? Now I want to pass in more terms that the Fetching Strategy needs.
Possible solutions
Some of the examples I've seen use a predicate - an expression that returns true or false if a particular Aggregate Root should be part of the result set. This works fine for conditions but what about getting back the first n customers and no more? Or getting page 2 of the search results? Or how the results are sorted?
My first reaction is to start adding generic parameters to my IStrategyForFetching<ICustomerInList> It now becomes IStrategyForFetching<TAggregateRoot, TStrategyForSelecting, TStrategyForOrdering>. This quickly becomes complex and ugly. It's further complicated by different repositories. Some repositories only supply data when using a particular strategy for selecting, some only certain types of ordering. I would like to have the flexibility to implement general repositories that can take sorting functions along with specialised repositories that only return Aggregate Roots sorted in a particular fashion.
It sounds like I should apply the same pattern used at the start - How do I make roles explicit? Should I implement a strategy for fetching X (Aggregate Root) using the payload Y (search / ordering parameters)?
Edit (2012-03-05)
This is all still valid if I'm not returning the Aggregate Root each time. If each interface is implemented by a different DTO I can still use IStrategyForFetching. This is why this pattern is powerful - what does the fetching and what is returned doesn't have to map in any way to the aggregate root.
I've ended up using IStrategyForFetching<TEntity, TSpecification>. TEntity is the thing I want to get, TSpecification is how I want to get it.
Have you come across CQRS? Udi is a big proponent of it, and its purpose is to solve this exact issue.
The concept in its most basic form is to separate the domain model from querying. This means that the domain model only comes into play when you want to execute a command / commit a transaction. You don't use data from your aggregates & entities to display information on the screen. Instead, you create a separate data access service (or bunch of them) that contain methods that provide the exact data required for each screen. These methods can accept criteria objects as parameters and therefore do searching with whatever criteria you desire.
A quick sequence of how this works:
A screen shows a list of customers that have made orders in the last week.
The UI calls the CustomerQueryService passing a date as criteria.
The CustomerQueryService executes a query that returns only the fields required for this screen, including the aggregate id of each customer.
The user chooses a customer in the list, and chooses perform the 'Make Important Customer' action /command.
The UI sends a MakeImportantCommand to the Command Service (or Application Service in DDD terms) containing the ID of the customer.
The command service fetches the Customer aggregate from the repository using the ID passed in the command, calls the necessary methods and updates the database.
Building your app using the CQRS architecture opens you up to lot of possibilities regarding performance and scalability. You can take this simple example further by creating separate query databases that contain denormalised tables for every view, eventual consistency & event sourcing. There is a lot of videos/examples/blogs about CQRS that I think would really interest you.
I know your question was regarding 'fetching strategy' but I notice that he wrote this article in 2007, and it's likely that he considers CQRS its sucessor.
To summarise my answer:
Don't try and project cut down DTO's from your domain aggregates. Instead, just create separate query services that give you a tailored query for your needs.
Read up on CQRS (if you haven't already).
To add to the response by David Masters, I think all the fetching strategy interfaces are adding needless complexity. Having the Customer AR implement the various interfaces which are modeled after a UI is a needless constraint on the AR class and you will spend far to much effort trying to enforce it. Moreover, it is a brittle solution. What if a view requires data that while related to Customer, does not belong on the customer class? Does one then coerce the customer class and the corresponding ORM mappings to contain that data? Why not just have a separate set of classes for query purposes and be done with it? This allows you to deal with fetching strategies at the place where they belong - in the repository. Furthermore, what value does the fetching strategy interface abstraction really add? It may be an appropriate model of what is happening in the application, it doesn't help in implementing it.