RoutingKeys & AggregateIds - What would be the best practices ?

Hello,

I’m trying my hands at Axon and I must say I really like it. Didn’t know it existed and ended up doing and event sourced application from scratch about 2 years ago. Axon would have definitely helped on the matter back then if I had found it!
Anyway, I went with the axon quick start videos and am trying to make it run. My current issue is that what is said in the video has since then evolved - you actually need a RoutingKey in your create command.

So here are my questions and thoughts:

  • It doesn’t feel natural to me that the one that will emit a command generates the aggregate ID. Am I wrong in thinking that ? What would be the reason to give this kind of responsibility to the one that emits the command ? it feels like it should be a responsibility of the domain event handler.
  • I see in the Axon-trader project that you are using Objects in place of IDs: objects that contain a single identifier field that ends up being filled with a UUID. Can you tell me more about this and the reason behind it ? I could guess part of that answer but I’m not sure.
  • It also would feel weird to create a specific property only used for routing purpose and it would probably be best to override the routing strategy in that case but I’m wondering then why isn’t this done by default ? We could mark / detect create commands to avoid the need for a routing key by default.

I’m interested in knowing what lead to those design choices so I can better understand the mindset behind axon the responsibility of each part of the application and project myself in my next project that will definitly be using your framework.

Thanks
Regards
Laurent

Hello Laurent,

Let me go through your points to shed some light on the situation.

It doesn’t feel natural to me that the one that will emit a command generates the aggregate ID. Am I wrong in thinking that ? What would be the reason to give this kind of responsibility to the one that emits the command ? it feels like it should be a responsibility of the domain event handler.

Whether it makes sense to create the aggregate identifier on the dispatching end is actually up to the domain if you ask me.
I’ve seen both ways around make sense on the matter, although I perfectly understand the assumption that the handling side should be in control here.

This means there’s no “one answer suits all”, as it depends on what you are actually trying to solve here.

I see in the Axon-trader project that you are using Objects in place of IDs: objects that contain a single identifier field that ends up being filled with a UUID. Can you tell me more about this and the reason behind it ? I could guess part of that answer but I’m not sure.

The idea behind having a typed identifier is to be more exact with what the intent is of the identifier.

For example assume you have an Aggregate with several Entities contained in it, all with their own identifier attached to it.

If you would just use String or UUID, your code could start looking a little ambiguous on the matter.

To make things worse, it could happen that somebody accidentally mixes up the UUID’s, leading to a pretty difficult to figure out issue.

Added on top of this, it provides you the option to add additional logic to your identifier object.

Granted, this isn’t always necessary. But starting off with typed identifiers allows this flexibility at a later stage if necessary.

It also would feel weird to create a specific property only used for routing purpose and it would probably be best to override the routing strategy in that case but I’m wondering then why isn’t this done by default ? We could mark / detect create commands to avoid the need for a routing key by default.

The only simple answer here is “legacy”. The introduction of Axon Server more forcefully made Axon applications distributed by nature.
This did shine light on the necessity of having an @RoutingKey annotation, but did not opt to change the default AnnotationRoutingStrategy just yet.
Reason to not change that? Backwards compatibility really. I am confident things will change in the future.

Hope this helps you further Laurent.

Cheers,
Steven