I have an aggregate which can have some child entities where the entity id is just a surrogate value (eg. a guid). The entity has another value that must be unique within the aggregate. The command also has some extra data that needs to be validated (eg. min temp must be <= max temp). There will be an Add command and a Change command. On one hand, I feel like maybe I should route the Change command to the entity. On the other, I’m not sure if it’s feasible since I need to ensure the uniqueness of the value should the command specify a new value. Just curious if there’s a recommended approach here in order to avoid putting too much functionality into the aggregate. Thanks!
Currently you’ll have to have command handler in the aggregate if you want to check uniqueness between entities. There is feature which is already implemented and scheduled for 3.3 release of AxonFramework that will help you achieve this. You can put @CommandHandlerInterceptor annotation in the aggregate and do the uniqueness check there, and put @CommandHandler in the entity in order to do the command processing. With this approach you can separate command validation (based on the state of the aggregate) from command handling.
Stay tuned for 3.3 release :)!
Hi Brian, Milan,
Aside from what Milan suggests, which could for example be used to disregard handling a command all together (which I believe is not part of your scenario), there is no one off solution for where to put your command handlers. Putting it differently, ‘it depends’ what the best approach is
I’d personally introduce your command handlers in the entity which logically would be in charge of making the decision whether a command should be executed or not.
Thus, if the ‘ChangeCommand’ you’re talking about is ‘the request to make some change’ in an entity, I’d let the entity make the decision whether it is okay to perform that action. If it is however a change on the Aggregate Root, I’d add that
@CommandHandler annotated function for the ‘ChangeCommand’ in the Aggregate Root.
As a last note, it is not bad by default to have a lot of functionality in your Aggregate. It might however point out that the Aggregate Root you choose encompasses to big a portion of you Domain Model. Or it is the right size, and your Aggregate is just super important.
Again, the recommended approach really depends on the situation your in.
That’s my two cents.
Both responses are much appreciated. What I’ve done for now is put the command handler on the root. From there, I will check the uniqueness on the non-EntityId value and then pass the command to the entity itself to validate the other data and apply the event if everything checks out. This would be more along the lines of the feature Milan mentioned until that version is released.