2

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

barii
  • 343
  • 1
  • 3
  • 12
  • Is adding mandatory questions a user action or a rule that occurs at some point in the Questionnaire lifetime? If so, during which state transition does it happen? – guillaume31 Jul 25 '18 at 08:01

1 Answers1

1

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

rascio
  • 8,968
  • 19
  • 68
  • 108
  • thanks for your answer From what I heared so far, command and query could be in different microservices. If they are, the only way to access the read model from the command handler would be via web api. And thet violates "don't ask, tell" – barii Jul 20 '18 at 14:00
  • The problem of reading a "read model" in the command side, is that only the data contained in your aggregate are consistent, each time you need to use/read data outside of the aggregate owner of the command you can't trust that they are the latest version. Basically you have 2 ways to solve this: 1. expand the aggregate boundary so that it contains all the data needed in your command execution. 2. query data external to the aggregate and "tolerate" the fact that they can be stale – rascio Jul 20 '18 at 14:26
  • It seems that you are in a situation where you can "tolerate" the stale data meanwhile expanding the aggregate boundary will create big locks in your application (about this I did a better explanation in this other question https://stackoverflow.com/questions/32822302/why-limit-commands-and-events-to-one-aggregate-cqrs-es-ddd/32826589) – rascio Jul 20 '18 at 14:28
  • 1
    @rascio is right, but I would just add that querying a read model from your write model may introduce eventual consistency problems\race conditions. It may be just fine or maybe not. Just be aware of this fact. – Savvas Kleanthous Jul 26 '18 at 12:14
  • 1
    @SKleanthous yes you are right! That was what I meant with _tolerate stale data_. – rascio Jul 26 '18 at 13:54