✅ How much validation should be performed against the CQRS command itself vs in the handler?
For example, let's say I have a database with this schema:
and the command is to invite a bunch of people to their birthday party, but only people who live in the same city are allowed to come, and the invitation must be sent at some point in the 30 days prior to the party date, and the party date has to be within +-7 days of their actual birthday:
So, as far as validation of the command itself goes, I see two options:
1) Validate that the
Host
and all the Guests
are not equal to Guid.Empty
, and that the PartyDate
is some time in the next 30 days. And that's as far as I could really go without a DbContext
. Then in the handler, I would actually do the rest of the validation.
2) Inject a DbContext
into the command validator and then I'd be able to validate everything before it even reaches the handler, and then the job of the handler would be reduced to just the act of actually sending out the invitations (however that happens).
Which is generally considered to be the better pattern?
I have a feeling that #1 is the better pattern, for two reasons. One is that doing all that validation outside the handler feels like "hiding" it. And two is that doing all that validation outside the handler would take the query that the handler is going to have to send and effectively turn it into work that's already been done, and therefore just making the handler re-send the same query that the validator has already sent.
But I just thought I'd get a second opinion.8 Replies
Generally, commands only do basic input validation. This should be quick and cheap, so stuff like "hey this is empty, we need a non-empty string" or "that number is too big/small".
for stuff like "this value already exists in the database"; thats something the handler takes care of
Imho number 1 is more nuanced, you're validating that you can try to process the command. When you say as far as you can go, you might be robbing what should be in the handler. But you may even have a model that gets validated and converted to a command and then handled.
okay so it does sound like #2 is going way too far
Async validators tend to be problematic imho
okay. Thank you! I really just needed a second opinion on it. I think that answers my question.
How do I remove this post?
Don't
oh
okay
There's is a close command
/close