7
votes

In my CQRS architecture, I'd like to validate that when I send a InsertSettingCommand (setting is a key/value object), I want to check that the key doesn't already exist in my database. If I understand CQRS & validation well, it says that the validation should be performed in client side only when it's about verifying some formatting stuffs like checking that email respects some syntax or that customer's name is not empty. But in my case, I need to query my database to see if it exists, but I don't know if it's correct to query my read store in client-side ? Or should I call my read store in my domain side ? Then throws an InsertSettingDuplicated event ?

So what's the best approch to take in my situation in a CQRS environment? Some people talk about compensating actions ? Is it something that can helps me ?

Thanks.

3

3 Answers

9
votes

It is ok to make query from client side to read storage in order to validate uniqueness. Here is some thoughts from Greg Young about set based validation using CQRS.

3
votes
  1. Use 'compensating actions' if you need fix some wrong commands thats break your read/write store.
  2. It is corrent to use Read storage to validate something before send command, in order to send valid command, no doubt.
1
votes

In theory, you shouldnt need to even check for a duplicate key, your client side should be wired up to retrieve such info on its own, completely segmented from user input. For example: have a list of such items in a drop down, or any other selective list.

Compensative actions or compensative commands should only be used when the system failed to perform a process, and thus has to rollback a few commands or whatever it has done in the build up to the failure point.

For example, lets say the system has to insert a setting, the only event that this command should be able to raise should be something like 'SettingInsertedEvent'. So assume that this event was not raised, we can then instruct the system to compensate for this, and rollback anything it has done within that process.

Your command could also implement an interface that does the checking for you via a dataManager. Or you could just build up a dataModel without a key, and make the table auto-increment so you do not even have to worry about the scenario completely. (Im sure you know by now that a dataModel is just a code representation of an existing table in your db server, linked to it by an ORM, another fundamental part of any modern application.)