--
You received this message because you are subscribed to the Google Groups "DDD/CQRS" group.
To unsubscribe from this group and stop receiving emails from it, send an email to dddcqrs+unsubscribe@googlegroups.com.
Visit this group at https://groups.google.com/group/dddcqrs.
For more options, visit https://groups.google.com/d/optout.
To unsubscribe from this group and stop receiving emails from it, send an email to dddcqrs+u...@googlegroups.com.
One of the things that seems to be a "rule" is that aggregates shouldn't expose internal state
To unsubscribe from this group and stop receiving emails from it, send an email to dddcqrs+unsubscribe@googlegroups.com.
In our project Location is an aggregate. It used a lot and if we made all locations entities in a larger aggregate we would run into significant concurrency issues. We do need to have relationships between locations. I have an AddRelationship method on the Location. The location then emits a RelationshipAddedToLocationEvent. The problem I have is where and when to get the data I need for the aggregate, process manager and projections.
If the aggregate needs to enforce an invariant about itself but needs data from the second location to do so then how does it get the data. Should the two locations be loaded in a command handler and the second passed to the method on the first? If aggregates aren't meant to expose their state then that doesn't make sense. Is it just that aggregates don't expose their data for modification? Or, should I query the read model for data about the second location?
What data should the RelationshipAddedToLocationEvent contain. Should it only have the two location ids or data from both locations? If a process manager handles this event and needs to make a decision about which command to send based on data from both locations how does it get the data. If only the ids are in the event then would it need to go to the read model? If all the data it needs is in the event then there is no need to do this.
It's the same for projections. If, for performance reasons I want to denormalise the data and write information about both locations to a single row then what's in the event is important. If it's only ids then I would need to query the read model again.
I've read lots on the subject and the advice seems to be inconsistent and contradictory. If the aggregates are the truth then surely I should be using them wherever I can in order to make business decisions. At the moment my events are full of ids and I'm constantly having to go to the read model in command handlers, events handlers, process managers and projections to get extra data I need.
While my example is about a specific case I'm having these issues on a more general level with my whole system. I have Contract as an aggregate which lots of parts of my system need in order to make decisions both in aggregates and process managers and I have similar problems with that. Maybe I'm missing something very obvious in all this but any advice would be gratefully accepted.
As far as I know aggregates are the source of truth
Process managers are similar but respond to events and after making decisions it sends commands.
If the aggregate needs to enforce an invariant about itself but needs data from the second location to do so then how does it get the data.
Should the two locations be loaded in a command handler and the second passed to the method on the first? If aggregates aren't meant to expose their state then that doesn't make sense. Is it just that aggregates don't expose their data for modification? Or, should I query the read model for data about the second location?
The issue, of course, is that all but the last of these is vulnerable to the problem that while you are checking the current state, somebody else could be changing the copy of that state in the book of record.
So if you've got a graph, and you want the write model to ensure that the graph is immediately consistent after each write, then the graph needs to be contained within a single aggregate boundary.
In other words, there's a trade off here -- and you need to be weighing the costs of the alternatives (see Greg Young on Set Validation: http://codebetter.com/gregyoung/2010/08/12/eventual-consistency-and-set-validation/ ). There's no magic.
If a process manager handles this event and needs to make a decision about which command to send based on data from both locations how does it get the data
I've read lots on the subject and the advice seems to be inconsistent and contradictory.
One specific problem is to do with Locations. Locations are a representation of a physical location in the real world. In our case car dealerships head offices and a few other types. There are relationshis between dealerships and their head offices but not with other location types.
We have a screen to allow users to enter locations and a seperate screen to add the relationships. These can be between dealerships and other dealerships or dealerships and head offices. They are one way relationships and contain information about the type of relationship it is and some other data. The user selects a particular location then goes to a screen that lets them enter the other location and the data.
The command carries the locationid, relatedlocationid, relationship type, etc. The command handler loads the first location aggregate then needs to pass details of the second? Some business rules such as checking that the type is a valid type (head offices cannot be linked to other head offices, dealerships can only be linked to their dealerships or head offices, etc), checking that this relationship doesn't exist already, checking that the addresses of the locations are valid (they can't be in different countries), etc. In order to do these checks data is required about both aggregates but the only thing on the command is the ids. As far as I know these checks should be done in the aggregate?
So if the rules pass then the event that's raised in the aggregate should contain what data? We have several projections that are interested in this event in order to update read tables. They all want different parts of the data though. We have one report that needs bothe the relationships addresses, one that needs their ids and a display name to populate a drop down in the ui, one that needs info about the locations to show a list of all the relationships. Should all the data that all of these projections need be on the event? Should the aggregate emit several events? Should the projections look the data up in the read model? What if I add another projection that needs more of this data, I will need to change the event?
The last thing is that this event is part of a process manager. When a relationship is added we need to setup some payment information and do some work in other aggregates. Which other commands we send from the process manager is dependent on the data. If it's a relationship between two dealerships then different commands are sent than if it was a dealership and a head office. What happens if the data required to make Ts decision isn't available at the time the event is raised?
again, thanks for the reply and any help is appreciated. Maybe I just don't get the pattern but I definitely seem to be missing something.
Locations are a representation of a physical location in the real world