Best practices for renaming of event classes

Hi,

we are using Axon Framework in a productive application and have recently realized that we have chosen a wrong name (from the business point of view) for an event class. Therefore we decided to change the class name and the name of a single event attribute. Since the application is already running for a while there are already some hundreds of thousands of these events.

At the moment we are discussing how to do the event class renaming. From our perspective there are at least three different approaches:

  1. Rename class and attribute and create an Upcaster that maps the ‘old’ events to the ones with the new name.
  2. Create a new event class and new handler methods, keep the old event and handler methods and let the aggregate apply the new event.
  3. Do the renaming, stop the application, change the event payload type directly in the database and restart the modified application

Are there any best practices out there that could help us to decide which way to go?

Thanks in advance,
Torsten

BTW: We are using Jackson for the payload serialization, a PostgreSQL as event store and a MongoDB for the projections.

Hi Torsten,

My personal preference in this scenario is to take the described scenario one.

An upcaster which only adjusts the payload type is very simple to right (actually, I am thinking of providing a base class for this in the framework sometime soon) and does not impose much constraints on the performance.

I would omit option two because it maintains legacy code in your application, potentially indefinitely as (ideally) you maintain all your events, forever.

Option three is indeed an option, but this breaks with the conception that you cannot update your events.

From a pragmatic stance the updating of events might occur at some stage in your application’s lifecycle, but from personal experience I have only found that necessary once a ballpark of 250+ upcasters was reached.

So, to circle back, a simple “payload-type-upcaster” would be a best practise from my point of view.

Just as food for thought I’d like to add a fourth option.

You can also make your serializer more lenient by introducing a form of aliases.
The XStreamSerializer provides this functionality on the actual XStream, for the JacksonSerializer aliases can be introduced by providing a custom JacksonSerializer implementation which overrides the classForType(SerializedType) / typeForClass(Class) methods.

In your custom installment, you can then check for this unintended type and replace it for the actual fully qualified class name of said event.

Hope this helps you out Torsten!

Cheers,

Steven

Hi Steven,

thanks for your quick and helpful response. Especially you hint with the number of 250+ upcasters was very interesting because it gave us an idea about the performance aspects of upcasters. Also your proposed fourth alternative sounds reasonable and worthwhile to think about, at least for some scenarios
Regarding the “payload-type-upcaster”: Do you already have some kind of shareable base implementation idea or some code snippets?

Kind regards,
Torsten

Hi Torsten,

Regarding the “payload-type-upcaster”: Do you already have some kind of shareable base implementation idea or some code snippets?

No I did not, but just take the liberty to create one, for which I will likely provide a pull request soon.

Without further ado:

twitter-icon_128x128.png

Hi,

if you are interested in alias names for your class names, you can have a look at:
github.com/JohT/alias

This way you could at least decouple the full qualified class name (implementation detail) from your domain event name and change class names without bothering about upcasters. It doesn’t depend on anything else than java se and uses standard APIs like resourcebundle and annotation processing (build time).

Your question made me think about extending this library to support multiple aliases…
This may solve the problem you described on serialization level…

Kind regards. Johannes.

Hi Johannes,

at a first and cursory glance this sounds interesting and we’ll definitely take a closer look at it. Thanks for the link!

Kind regards,
Torsten

I’ve just finished the enhancement “Support multiple aliases for one type” and released it with version 1.1.0.