Axonframework: Alias/Business Name for an Event

Created on 20 Aug 2018  路  11Comments  路  Source: AxonFramework/AxonFramework

In some cases, it would make sense to have an alias (or some kind of semantic business name) for an event. Those cases could be that you want to refactor the structure of your core-api or you have two separate applications that cannot share the core-api but want to communicate with the same event scheme.

Should Enhancement

Most helpful comment

I recently published a working and tested solution to my GitHub repository:
JohT/alias

This is for now a "outside axon" idea only. I tried quite some ways and endet up with this solution.
If i should try a pull request for this feature (part 2 with the resource bundle aware serializer),
please comment (or write me). It does not need to be done that way. We can discuss it.

Part 1: ResourceBundle generator for @TypeAlias annotated types:
"type-alias" provides the annotation @TypeAlias to assign types a distinct alias name.
It generates a (customizable) ResourceBundle containing all aliases and their types.
Since ResourceBundles support Objects, the types are directly represented by their Class-Objects.
"type-alias" is pure Java SE and compile-time only. @TypeAlias is not needed and not present at runtime.

Part 2: ResourceBundle alias aware axon serializer
"type-alias-axon-serializer" provides a decorator for serializers. It reads the generated ResourceBundle and handles alias names. It also supports type names for backward compatibility.
I tried to also provide a solution for direct Class resolution (instead of Classloader.load...),
but this was not fully possible (as a decorator) without any change of axon.

For details have a look at the example projects (e.x. "type-alias-example").
"type-alias-axon-serializer-integration-test" contains a full running axon example for JavaEE using arquillian. This may also be interesting for those who want to use axon with Java EE (as a playground).

The artifact will be published to maven central soon.

All 11 comments

Maybe by providing some form of annotation, like @EventAlias(String[] aliases)? :thinking:

@smcvb How would a String Array work?

When using EventSourcing with Axon, there's exactly one String within the payload_type column. Though I'd say, that an Event should have exactly one Name / Alias / Type.

I'd call it type, because it's the same name as for Aggregates: @Aggregate(type="Foo").

@benneq I am not yet sure how that would work and if it would work at all.
This was just my thoughts roaming freely in regards to this issue.

Further discussion will proof whether my suggestion makes sense at all I assume.
Your contribution to this is very valuable of course, thus thanks for you reply :)

Discussion is always great and leads to the best solutions :)
Then let me ask another question: Why an array?

I think an event should have exactly one name. If you need a second event with the same payload (but with a different type / name) , you could just use class inheritance.

I think it would be best to have an @Event annotation. Then it would be possible to do more configuration later on.

For example:

@Event(
  nameForWriting="FooEvent",
  namesForReading={"FooEvent", "com.foo.bar.events.FooEvent"}
  customDeSerializerForThisSpecificEvent=FooDeSerializer.class
)

Just some things that came to my mind. Doesn't have to be useful at all.

EDIT:
How does MongoDB Integration handle Event Types / Names when using Event Sourcing?

Does Axon provide the name or does the Java MongoDB Client handle this?

We should probably add this information on serializer level. Mapper should be provided to the serializer stating how the event class is mapped to the payload type and vice versa.

It would be nice, if the new Annotation is also able to be used via a meta-annotation.

Any news or plans for this feature?

This would also make refactoring much easier, because the event type name doesn't depend on package and class names anymore.
And it would provide interoperability with other event consuming services / applications written in different languages, if they could simply look for ORDER_PLACED instead of org.foo.bar.some.more.nested.package.names.OrderPlacedEvent

I don't need an annotation provided by axon. It would be enough if we can inject somewhere a custom TypeNameResolver or something similar.

I played around on my own with Jackson (JSON Parser) and the build in type inheritance features.
The goal was to have an Interface, which is implemented by some events.
These events could get stored as list of the interface type e.g. in a Saga and are distinguished by a String name.
I ended up with too many annotations and it blew up complexity.
It worked but it wasn鈥檛 worth it IMO.

The hard thing here is to get a register of names mapped to the class.
If it should be easy to use, you need to discover the event annotations.
The event api module would be dependent of cdi or asm or some other kind of lib.

On the other hand it could also be done by registering the events in the configuration.
This way you are not dependent of magic, but you need to think of the config entry every time you add an event. This could be the base, but there need to be at least unit tests or build steps to ensure
that every event is registered and there are no duplicate names.

It could also be done the old way using a mapping configuration file that contains all events and gets automatically filled by a compile time feature or build step.

@benneq: We're currently hard at work resolving 4.1 along the entire Axon eco-system - this means a heavy focus on server. As soon as this is shored up, we will be evaluating which submitted and new issues we'll pick for 4.2. Thus for now, I cannot give you a time frame.

In the mean time, I think @JohT is giving a fair suggestion how to do something like this yourself.

I recently published a working and tested solution to my GitHub repository:
JohT/alias

This is for now a "outside axon" idea only. I tried quite some ways and endet up with this solution.
If i should try a pull request for this feature (part 2 with the resource bundle aware serializer),
please comment (or write me). It does not need to be done that way. We can discuss it.

Part 1: ResourceBundle generator for @TypeAlias annotated types:
"type-alias" provides the annotation @TypeAlias to assign types a distinct alias name.
It generates a (customizable) ResourceBundle containing all aliases and their types.
Since ResourceBundles support Objects, the types are directly represented by their Class-Objects.
"type-alias" is pure Java SE and compile-time only. @TypeAlias is not needed and not present at runtime.

Part 2: ResourceBundle alias aware axon serializer
"type-alias-axon-serializer" provides a decorator for serializers. It reads the generated ResourceBundle and handles alias names. It also supports type names for backward compatibility.
I tried to also provide a solution for direct Class resolution (instead of Classloader.load...),
but this was not fully possible (as a decorator) without any change of axon.

For details have a look at the example projects (e.x. "type-alias-example").
"type-alias-axon-serializer-integration-test" contains a full running axon example for JavaEE using arquillian. This may also be interesting for those who want to use axon with Java EE (as a playground).

The artifact will be published to maven central soon.

Thanks for sharing this with everybody here @JohT!

Was this page helpful?
0 / 5 - 0 ratings