CQRS (event sourcing) reading multiple aggregates - domain-driven-design

I have 2 aggregates, which have kind of 1-to-many relationsip. For example, I have a list of questions, and I want to add some of them to questonaires, some of them are mandatory and must be added to all questionaires, some of them are not, and the creator of the questionaire choses them.
Let's say I am using event sourcing and CQRS. I create the list of questions, and I want to add the mandatory questions to the questionaire.
Normally I would do
questionaire.AssignQuestions(questions.Where(q => q.isMandatory).Select(q => q.Id))
something similar. But in CQRS I shouldn't use the query model for this. But in the command model I am using event store, so I would have to replay all events on all questions, and that doesn't seem to be reasonable.
Most probably my model is not event oriented enough, but I don't really have a better idea at this point. How should I model this?
thanks

You command handler can query a read model to retrieve the list of the question ids to form the questionaire.
But in CQRS I shouldn't use the query model for this.
This is just a false myth

Related

Domain Driven Design, How do I deal with user specific data?

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

What is the best way to fill updated data from one aggregate root to another?

I try understand what is the best way for filling property from one Aggregare Root to another.
I have Model Aggregate Root, Category Aggregate Root, Filter Aggregate Root
Every Model can have some Filter list, and can be in one of the Category. Category can have a Filter for inheriting to the Model. When Category property of the Model is updated, Filter must be inherited from Category to the Model, and when Filter property is updated in the Category, all Models from that Category must inherit new value. All inherited Filters can't be updated, but manually added filters can be edited.
One way I "invent" is using Process manager with state which contains Category filter and Models list.
So I will have such behavior:
Category AR UpdateCategoryFilter (command) -> CategoryFilterUpdated (event)
Model AR AddCategory (command) -> CategoryAdded (event), RemoveCategory (command) -> CategoryRemoved (event), InheritFilter (command) -> FilterInherited (event), RemoveInheritedFilter (command) -> InheritedFilterRemoved (event)
Filter AR CreateFilter (command) -> FilterCreated (event)
Process Manager FilterInheritance have correlationIdResolver by categoryId, triggers on [CategoryFilterUpdated, CategoryUpdated] events
PM behavior is like:
current State(filter, models) =>
if CategoryFilterUpdated(... newFilter ...) =>
set new State(... newFilter ...) {
models.forEach(send InheritFilter(model, newFilter))
}
if CategoryAdded(.... modelId ...) =>
set new State(... models.add(modelId) ... ) {
send InheritFilter(modelId, filter)
}
if CategoryRemoved(.... modelId ...) =>
set new State(... models.remove(modelId) ... ) {
send RemoveInheritedFilter(modelId, filter)
}
Is this a right way? Is there some other ways?
Remember, Aggregates are for protecting domain invariants when making state changes, not for simple CRUD. It's not clear what your domain is, and what kind of commands might be sent to a 'Model' where protecting invariants requires knowing what the 'Filters' of the Model are.
You only need to send a command to an Aggregate if the command needs to be validated against the state of the aggregate, or if the command will affect handling of future commands that might be sent to the aggregate. It's not clear whether this is the case for you. Does the Model aggregate have to validate commands/emit events based on the Filters it has? If not, the way to handle this is to do it purely on the read-side - the read side can keep track of the current filter for a Model, and clients/processes can use it as necessary. So, your Model read projection will just need to listen for CategoryAdded, CategoryFilterUpdated, etc. to update the read view of the Model.
If you really do need the Filters to validate Model commands or emit appropriate events in response to those commands, then what you've got seems like an option. But examining your business requirements to see whether filtering could be done outside of the Model aggregate, etc. would be valuable, since copying commands between aggregates increases coupling - you also have a race condition between sending the InheritFilter, etc. commands and the client sending a command to the Model that needs that filter, which seems like a problem that might need client handling to poll for the Model to be ready for the command.
It looks very much like you are doing CRUD style data manipulation operations rather than taking a domain approach.
Another issue you may be having is assuming you can use Aggregate's to display information on the UI. Aggregates don't in principle have any externally visible properties (no getters except the ID). If they did they wouldn't be well encapsulated. You are better off using a read model for use on the UI. This article may give you a better overview of how a typical CQRS application is structured: CQRS + Event Sourcing – A Step by Step Overview
Assuming you are looking to use a DDD style approach I would first have a look at your aggregates. I don't know your domain but from a surface view, it looks like just 1 aggregate root. Not sure what it would be called as I don't know anything about your domain.
I wouldn't expect, for example, real users would say things like "InheritFilter". You may also wish to take a look at this article to help you with how to name your events and by implication, your commands: 6 Code Smells with your CQRS Events – and How to Avoid Them
I hope this helps clear up some of your issues. I personally found getting my head around DDD, CQRS and event sourcing very difficult. I was having to unlearn a bunch of stuff. But I'm a better developer because of it.
Hope this helps.

Event Sourcing and total aggregates encapsulation

I came across that Event Sourcing assumes total encapsulation. Aggregates dosen`t allow to access their internal state. State is internaly kept only to impose valid transions. As far as I grasp this aggregates (in terms of outside world) just emits events. And I cant get my head around that actualy. I refine my models to reflect my bussiness needs which leads to objects that publish some API. For example, I have two aggregate roots: cart and order. I would like to build my order using ActiveItems from cart:
$order->addItems($cart->getActvieItems)
But this violates ES assumtion about total encapsulation of aggregate state. How order should be fulfilled with ActiveItmes according to ES good practices? Should I use read model? I think this leads to knowleadge leak out of the model (aggregate). Thank you in advance!
Alexey is right in that the Event Sourcing is just a persistence mechanism. I think the confusion comes when thinking about Aggregates. Encapsulation is an important concept when thinking about Aggregates. The implication here is that they are not used for query or the UI. Hence the reason CQRS fits in so well.
But most applications need to query the data or display things on the UI. And that's where Read Models come in handy. Assuming you are using CQRS and Event Sourcing (which you don't have to when using Aggregates) it's a fairly easy thing to do. The idea is to subscribe to the events and update the Read Model as you go. This doesn't 'leak' anything because the functionality is in the Aggregate domain objects.
Why is this a good thing?
Have no or extremely limited dependencies makes the aggregate's much simpler to work with.
Read models can be highly optimised for reading from and therefore very fast.
Read models don't require complex queries and joins.
There is a clear separation of concerns
This approach offers huge scaling potential
It's easy to test
I'm sure there are more. If it helps I have a blog post outlining a typical CQRS and ES architecture. You may find it helpful. You can find it here: CQRS + Event Sourcing – A Step by Step Overview
Event Sourcing does not assume anything in addition to the fact that you save the state of your object as series of events. There is even no requirements to have an "aggregate" when doing Event Sourcing.
If you are talking about the DDD terms Aggregate and Aggregate Root, again, Event Sourcing is just a way to save the object as a stream of events instead of the last actual state. There are no additionally imposed "requirements" like "total encapsulation" and inaccessibility of the internal state. Of course aggregates (and other objects) have state.
What could be confusing is that if you also use CQRS, you can have your aggregate state not being used since all its data is transient to the read model. But this is something else and does not need to be blindly applied.
Again, Event Sourcing is just a persistence method, nothing more, and nothing less.
$order->addItems($cart->getActvieItems)
In addition to the comprehensive coverage of CQRS in the answers, I'd like to point out that in the message driven systems commands(messages) should be self-contained and have all information encapsulated necessary to perform the action.
In the above example, Order aggregate receives command AddItems with the list of Items Ids as a payload. The fact that AddItems command handler needs to get additional information to handle the command points to a problem. AddItems command has no sufficient payload so Cart and Order are semantically coupled. You would want to avoid that.
Message passing reasoning is the key here. Here are some abstractions
class AddItems : Command
{
List ItemIds {get; set;}
}
class Order
{
void AddItems(AddItems command){}
}

Business Process to "Transfer" a one-to-many association

Introduction To Domain
I have a Salesman. A Salesman gets BusinessOpportunity's. Both make sense in my domain to be ARs.
There are two ways to model this:
A Salesman aggregate is unaware of its business opportunities, or
A Salesman is aware of his list of opportunities (using an OpportunityId of course)
A BusinessOpportunity, I believe, always needs to know its SalesmanId.
The Question
I have a business process that I plan on implementing using a Process Manager pattern. It is a "TransferAllBusinessOpportunities" process. It means taking 1 salesman and "transferring" all of his/her opportunities to the other.
How should we do this? and how should we model the domain?
I can think of a process state machine if we model this as a bidirectional association, but its quite involved. I don't know how to do it if we only have a unidirectional association because we'd then need to resort to the read model to get the list of business opportunities to transfer and I'm worried that we should keep everything in the write-side model. What do you think about that?
Any help is very much appreciated. Attached a diagram below to help visualize if that helps.
A quick roundup of the questions:
How would you tackle this problem?
How would you model the domain to best tackle this?
Is it ok to use the read model in a command handler to execute the business process?
Thanks again.
Meta-answer: you need to read what Greg Young has to say about set validation. You'll be in a better position to explore your requirements with your domain experts.
I don't know how to do it if we only have a unidirectional association because we'd then need to resort to the read model to get the list of business opportunities
Extracting the data from the read model should be your first resort. What's the problem?
Basic outline
Query the read model for the set
Create command(s) to update the write model based on the set
Dispatch the commands to the write model
the write model gets the set data it needs from the command (not from the read model)
The first resort won't always satisfy your requirements, but it's a good starting point for thinking about the use case. What problems could occur if you implemented this simple way? what would those problems cost the business?
Also: I said commend up above, but it might not be. One thing that you didn't describe is what part of the model "decides" the transfer. Is the model allowed to reject the command to transfer the opportunity? Under what circumstances? which aggregate holds the state that determines if the transfer is allowed?
It might be that the transfer isn't being described as a command, so much as it is by an event, describing a decision made by some human sales manager.
I'm worried that we should keep everything in the write-side model
Maybe. Is there a business invariant that needs the state of the set? So far, it doesn't sound like it, which strongly implies that the set does not belong in the write model. You want to strip down your aggregates as far as you can without losing the ability to enforce the invariant.
Is it ok to use the read model in a command handler to execute the business process?
Is it "ok"? Judging from what I have read in various places, a number of people think so. Personally, I'm not convinced. Roughly, you are looking at two broad outlines
Create a thin command
Send the command to the command handler
Query the read model to flesh out the missing details
Process the fleshed out command
vs
Query the read model
Use the query results to construct a fat command
Send the command to the command handler
Process the command
I've yet to see an example where the business would care about the distinctions between these two implementations; the latter implementation is easier to predict (you don't need to know anything about the state of the read model, just the state of the aggregate and the state of the command).

Do we really need a separate event store with Event Sourcing and CQRS patterns?

Suppose we have a situation when we need to implement some domain rules that requires examination of object history (event store). For example we have an Order object with CurrentStatus property, and we need to examine Order.CurrentStatus changes history.
Most likely you will answer that I need to move this knowledge to domain and introduce Order.StatusHistory property that contains a collection of status records, and that I should not query event store. And I will agree with you.
What I question is the need of Event Store.
We write in event store events that has business meaning (domain value), we do not record UserMovedMouse events (in most cases). And as with OrderStatusChanged event there is a high chance that most of events from EventStore will be needed at some point for domain logic, and we end up with a domain object that have a EventHistory property with the collection of events.
I can see a value in separate event store for patterns such as CQRS when you have a single write only event store and multiple read only query stores, which gives you some scalability. However the need to to introduce such thing in code is in question too for me. All decent databases support single write server, multiple read servers scalability (master-slave replication). Why should I introduce such thing at source code level? Why not to forget about Web Services, and Message buses and use write your own wrapers around Sockets.
I have a great respect to "old school" DDD as it was described be Eric Evans, and I see some fresh and good ideas in new wave DDD+SQRC+EventSourcing pattern aggregate. However the main idea of CQRS is under big question for me. Am I missing something?
In short: if event sourcing is not needed (for its added benefits or as workarounds for some quirks), then you definitely shouldn't bring it into your system just for the sake of it.
ES is just one of many ways to augment CQRS architectural style within a bounded context. It is not a requirement.

Resources