Set Based Validation API Idea

One of the ways to perform set based validation described on the blog post here is to:

  1. Maintain a table with the uniqueness constraint in a relational DB.

  2. Create an event handler for the event where we write the logic to ensure the set based validation invariant is maintained (code here).

     @EventHandler
     public void on(AccountCreatedEvent event, EmailRepository emailRepository) {
         emailRepository.save(new EmailJpaEntity(event.getEmailAddress(), event.getAccountId()));
     }
    
  3. Ensure the processing group is marked as subscribing (code here).

    axon.eventhandling.processors.emailEntity.mode=subscribing
    

Everything works fine but it is slightly annoying to have all this ceremony/boiler plate.

So how does this idea sound. Instead of creating an @EventHandler which is in a separate class from the aggregate we create a static method on the @Aggregate itself:

@Aggregate
public class Account {
    // fields/constructors elided...

   @SetBasedValidator
   public static void on(AccountCreatedEvent event, EmailRepository emailRepository) {
     emailRepository.save(new EmailJpaEntity(event.getEmailAddress(), event.getAccountId()));
   }
}

The framework would do the heavy lifting and automatically configure a subscribing event handler. If it is needed then the @SetBasedValidator annotation could take the name of the processing group.

This way you can very easily add the set based validator business logic.

I also thing it being in the @Aggregate class as a static method makes sense - because static reflects the fact that it will apply to all instances of the aggregate.

What do you guys think?

Hi,

I think the one thing missing is the command interceptor. In general, it sounds interesting, but there are flavors of implementations. Not sure the framework approach is a good one…

Cheers,

Simon

Hi Simon - thanks for your response.

Why is the command interceptor needed here? I thought that would be a different approach where you validate the invariant prior to the command handler being invoked.

In this case there shouldn’t be a need for it because the subscribing processor will fail if the invariant is broken (assuming a UNIQUE constraint on the table) and the unit of work should be rolled back.

but there are flavors of implementations. Not sure the framework approach is a good one…

I’m interested to understand what other approaches there are which are not framework based?

From my perspective the framework would benefit greatly by providing something like this to reduce the boiler plate and make intent clearer.

Regards,