2

There are many CQRS frameworks and event store libraries.

All of them use GUID as aggregate root's ID.

Those event store only let me query only by GUID.

I realise that there are many times in last project(DDD+CRUD) I need to query aggregate root using others fields rather than GUID.

Sometime use couple fields.

How to solve this problem?

Should I query read model inside command handler?

Or I need to build another repository to map properties to GUID?

Or I need to solve this problem by redesign the domain models and query things to get GUID before enter command? I asked it here

1
  • I have edited the whole question.
    – kitta
    Commented Jun 23, 2018 at 19:54

2 Answers 2

8

CQRS/ES is a tricky architecture in many aspects and you've found one of them.

First of all, since you're storing events it is very hard to query an entity based on its data since you don't actually have the entity-state stored anywhere, only the events that will generate such state. It won't work like a regular state-based storage where you can go into your record and query a person from its name, for an example.

So, for the command-side (the ES side) of your equation, you should only be able to reliably fetch a whole entity by its ID and then replay the events to rebuild its final state.

Now, of course, there are business scenarios where you will need to find a person from its name. When that happens, the easiest way to proceed is to simply query the read model and then proceed to fetch the ID to go get the command entity from it. Please be aware that the read-side is subject to a propagation delay from the command-side. That means it's only eventually consistent. Once a command is triggered and processed on the command-side, there will be a random period of time where the read-side will not reflect this latest change, so your code must be prepared for that.

However, you should really try to make your application layer communicate in terms of your entity IDs to avoid this extra step as much as possible and it shouldn't be that hard.

Imagine some client is reading data pertaining to one of your entities. If that is happening, that client probably already holds the ID information of that given entity. So if he wants to send a command to such entity, he should be able to fire it based on its ID and not on other state-based data.

0

According to the answer of @Pedro Goes If we do query to read model then our write model will be dependent on read model. I think the write model (domain) should be independent.

We can create write model specific read-model who only stores the final state of our aggregate. Using that read model we can do the necessary query.

Please note this read-model is not for UI Query. It is only used from write model to do necessary data validation.

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