Validate vs Apply

147 views
Skip to first unread message

N F

unread,
Jul 26, 2015, 6:36:37 PM7/26/15
to DDD/CQRS
I need help clarifying some confusion around designing Aggregates with EventSourcing in C#.
(I've seen some interesting examples in F#, but we aren't ready to switch languages yet).

My team and I are debating the usefulness of having a Validate function independent of the internal Apply function.
I've tried to explain that we don't want to execute our current validation logic when we load historical events; but this doesn't seem to translate.

One of their concerns is the shape of the resulting code; ie. having a long list of message handlers... reminds them of the WinMain event loop.
To the extent possible, they want all the relevant code immediately visible; so separating with partial classes is also unreadable.


1) Am I right to be concerned?  - Does ES require separate Validate/Apply functions?

2) Do you have examples of composing the Validate/Apply pair without resulting in a list of function pairs?

3) When using DDD+ES, should an aggregate only "accept and emit messages" or should we try to avoid the aggregate knowing it is EventSourced?


Brian Mavity

unread,
Jul 26, 2015, 6:51:11 PM7/26/15
to ddd...@googlegroups.com
Hi,

I guess it depends on how your aggregates are structured, but the most common way I read about this is:
  1. Commands are validated before they are applied to an aggregate (I usually do not apply commands directly to aggregates, but I have read about this being done, and conceptually it's the same.)
  2. Once a valid command is applied to an aggregate, if an invariant is violated, an exception is thrown.
  3. If the command is successfully applied, events are generated, applied to any necessary aggregate state, and saved to an event store.
  4. When an aggregate is loaded again in the future, only the events are applied and they do not need to be validated.
Short answer, only validate commands, if your team wants to store validation code in an aggregate, I don't think that would be killer. Don't validate events, just apply them, as they are immutable.

Hope that helps.

Brian

--
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+u...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

jarchin

unread,
Jul 26, 2015, 7:02:21 PM7/26/15
to DDD/CQRS, fulle...@gmail.com
What I've seen mostly is something along this line:

There is a basic validation of commands in some layer prior to the AR. Within the AR there is some more business specific validation, it can be anything really. If it fails, error is thrown, just as Brian describes. This means no events generated by that command will be saved.

OK, not only does the "Validate"-function validate, it can also be a place for calculations with the values available at the time of the event inception - like data from some external service. So the whole point of separating into the function-pairs, is to be able to build up the state from the events, exactly the same way every time. No need for validation, no need for recalculation. Just add to the state, event by event.

You must have the validate/calculate-part somewhere separate from the apply-part to be able to do ES. So if your team wants to merge the function-pairs, they're just pushing it out of the AR - and that's not recommended, since one of the pillars of the AR design is to encompass exactly that functionality.


Nescio

unread,
Jul 26, 2015, 7:58:23 PM7/26/15
to DDD/CQRS
Yes that was my concern, it seems to be breaking encapsulation. Thus far, my team is convinced that all data and service calls can be orchestrated outside the aggregate and therefore aggregates basically just expose an apply function - seems very anemic, but the prototype they built was only handling crud-like behaviors.

To my understanding, aggregates should completely encapsulate the business rules.

I prefer aggregates to only accept and emit messages - commands are basically a parameter object.

Unfortunately I am stuck, because I don't see an obvious way to avoid a long list of function pairs. However, in my experience the more separation between the validate and apply methods, the more likely a Dev will forget to update one or the other.

Chris Sampson

unread,
Jul 27, 2015, 5:32:41 AM7/27/15
to ddd...@googlegroups.com
Some validation will go into the aggregate, some outside of it. Validation for command inputs based on aggregate state should rightly belong in the aggregate and you would raise an event rather that an exception in order to act upon that validation (I.e. inform the user). Other validations, - is it a valid email?, is it greater than zero? should be outside of the aggregate unless you want to create specific events for that stuff. I use decorators on my command handlers specifically purposed for that low level command validation.

--
You received this message because you are subscribed to the Google Groups "DDD/CQRS" group.

Nescio

unread,
Jul 27, 2015, 5:51:33 AM7/27/15
to DDD/CQRS
Thanks for the response. Yes, my expectation is low level validation will occur in my value objects which, for inputs, are composed into the command object and then passed to the aggregate. To avoid wasting resources, I prefer this type of validation to occur as early as possible. The aggregate should only need to validate that the command is not null/missing and then focus on any business rules given its current state.

I would prefer not to have a "command handler" for every aggregate - a framework should be able to automatically dispatch the command to the appropriate handler on the aggregate and save the result. Ideally, I can pipeline a command handler only when I need it - ie to orchestrate a domain service or policy/saga.

Chris Sampson

unread,
Jul 27, 2015, 10:07:45 AM7/27/15
to ddd...@googlegroups.com
Not sure I understand the following:

"Yes, my expectation is low level validation will occur in my value objects which, for inputs, are composed into the command object and then passed to the aggregate.  
To avoid wasting resources,"

can you expand?


On Mon, Jul 27, 2015 at 10:51 AM, Nescio <fulle...@gmail.com> wrote:
Thanks for the response. Yes, my expectation is low level validation will occur in my value objects which, for inputs, are composed into the command object and then passed to the aggregate.  To avoid wasting resources, I prefer this type of validation to occur as early as possible. The aggregate should only need to validate that the command is not null/missing and then focus on any business rules given its current state.

I would prefer not to have a "command handler" for every aggregate - a framework should be able to automatically dispatch the command to the appropriate handler on the aggregate and save the result. Ideally, I can pipeline a command handler only when I need it - ie to orchestrate a domain service or policy/saga.
--
You received this message because you are subscribed to the Google Groups "DDD/CQRS" group.

Nescio

unread,
Jul 27, 2015, 10:48:02 AM7/27/15
to DDD/CQRS, sammos...@googlemail.com
Sure...

Validation is a continuum and will need to be evaluated at almost all levels within the application.
However, since value objects are the units of computation in the Domain, I want to translate all user input into value objects as early as possible.
By converting primitive values (strings, ints, dates, etc) into trusted domain objects (name, accountBalance, birthdate); I can avoid duplicate validation.
By composing commands with value objects, the aggregate only has to ensure the command is not null or missing - all other validation has already occurred (when constructing the command).
Since the application must construct the command and pass it to the domain, all user input is validated as part of the initial request (before migrating to a back-end service or queue, etc)

(Note: the client still passes a DTO and the application/API layer translates the inputs into a Command)

@yreynhout

unread,
Jul 27, 2015, 1:22:51 PM7/27/15
to DDD/CQRS, fulle...@gmail.com
1) most of the methods in an aggregate's entities are split up into guarding invariants + logic to compute the side effect and the application of said side effect (or multiple).
2) in C#? no. But then again, I wouldn't be too concerned (sometimes the split is an advantage).
3) depends on how close one is to the aggregate's code surface. You can convert one aggregate at a time, even one behavior at a time (depends on whether it's worth the effort). Don't know what problem you are seeing with this.

Nescio

unread,
Jul 27, 2015, 2:46:44 PM7/27/15
to DDD/CQRS
Yes, I'm definitely advocating to have a split between them. This is a Greenfield project, which we've built a POC for...so plenty of room to rejig at the moment

Kijana Woodard

unread,
Jul 27, 2015, 3:11:14 PM7/27/15
to ddd...@googlegroups.com
"...between them."

Between what exactly? 

I'm confused as to whether you are agreeing with @yreynhout or disagreeing? AFAICT, the "split" @yreynhout referred to is all within the aggregate.

On Mon, Jul 27, 2015 at 1:46 PM, Nescio <fulle...@gmail.com> wrote:
Yes, I'm definitely advocating to have a split between them. This is a Greenfield project, which we've built a POC for...so plenty of room to rejig at the moment
--
You received this message because you are subscribed to the Google Groups "DDD/CQRS" group.

Nescio

unread,
Jul 27, 2015, 3:30:45 PM7/27/15
to DDD/CQRS, kijana....@gmail.com
Sorry for the confusion, I tried to respond from my phone. To hopefully clarify...

1) I am advocating for a separation between Validate/Guard and Apply for each command on the aggregate. To do otherwise seems to break the abstraction.
2) I agree; I find the further the apply function is from the Guard function, the more likely the developer will be to forget to update one or the other.
3) I am advocating for the aggregates to only accept commands/emit events. There's nothing to convert yet, but I am concerned if we add a lot of ceremony to avoid making ES a first class citizen.

Nescio

unread,
Jul 27, 2015, 3:48:54 PM7/27/15
to DDD/CQRS
I think you and I agree. Unfortunately, I've been having a hard time convincing my team of the same.

Kijana Woodard

unread,
Jul 27, 2015, 3:59:45 PM7/27/15
to ddd...@googlegroups.com
What do they want to do?

"...having a long list of message handlers..."

This sounds like an invented concern. The number of Command/Event handlers is bounded by the scope of the aggregate. If it's unwieldy, the aggregate is probably doing too much.


On Mon, Jul 27, 2015 at 2:48 PM, Nescio <fulle...@gmail.com> wrote:
I think you and I agree. Unfortunately, I've been having a hard time convincing my team of the same.
--
You received this message because you are subscribed to the Google Groups "DDD/CQRS" group.

Nescio

unread,
Jul 28, 2015, 12:45:18 PM7/28/15
to DDD/CQRS, kijana....@gmail.com
I agree. They've projected their concerns from a POC where all actions were very CRUD based (ChangeName, ChangeSSN, etc).
Given that understanding, they've predicted all aggregates will look like large lists of these types of simple actions.
I've been trying to exemplify other, more complicated scenarios, but I am not yet fully familiar with the domain.
I've also advocated simply using CRUD in several domains where the only behavior is to update the record.

Given their basic example, and the "long list" concern they've factored out an aggregate builder that registers event handlers and interprets history by calling the appropriate function on the aggregate.
Unfortunately, the builder calls the same function as the command handler (invoking what would be validation logic, if it weren't simply a crud update)
So, instead of having the aggregate load itself, it seems to me they've broken the abstraction and limited the ability to change the Validation logic separate from the Apply.

Kijana Woodard

unread,
Jul 28, 2015, 2:39:58 PM7/28/15
to Nescio, DDD/CQRS
"...they've factored out an aggregate builder..."

It's always a bad sign when step 1 of introducing a new technique is "build an in house framework".

"I've also advocated simply using CRUD in several domains where the only behavior is to update the record."

Good idea.

"So, instead of having the aggregate load itself, it seems to me they've broken the abstraction and limited the ability to change the Validation logic separate from the Apply."

Yeah. This is a terrible idea. Events can't be validated as they can't be rejected. The validation rules for handling Commands can change over time. Kaboom.

Reply all
Reply to author
Forward
0 new messages