Is there a way to version events?

Howdy All,

I know it is a no-no to edit events once they have posted (besides perhaps logically hiding them). However, I think the ability to at least provide a new version of an event could be very useful. It would be up to the developer to ensure the semantics of the event don’t change etc.

For example, E1 is posted (lets call it’s version v1) and then the app changes so the format and representation of the events change (but not the semantics). In this case, it would be great to be able to upgrade E1 to version v2 once and save it, rather than doing this every time v1 is accessed.

The different versions would have the same eventId and both be kept (why not?). Applications could even ask for a particular version if they had not been updated to be able to handle the new version. Also, eventually it is likely that all cached copies of v1 would be eliminated in systems.

I assume it may be difficult, technically, to add new versions in a physically efficient way (e.g. if events are written to a sequential log) but perhaps this could be kept in mind when the architecture is reviewed in the future (unless it is already possible and I’m just unaware).



You can always copy one stream to a new stream and in the process do some transformation.

How does everyone feel about just leaving all [production] versions of Events in the code base?
Or having translator/upgrade as part of the stream reading process?

or just use json and weak serialization

OK, old thread, but one of the more recent on the subject.
I think this is a super important subject, don’t know if others do. My projects are constantly changing, evolving and improving. I rethink the events many times, and I do things that are essentially refuctors because everything would break if I would not adjust related parts of the system to the changes… (which can be alot of work, but is a must if previous solution was crappy).

Changing what the system needs from an already existing event, is a bit tricky. (The system depends on the events to transfer certain information).

Setting up new events + eventhandlers and keep the old ones around: I have thought that maybe just keep new eventhandlers in new files, and load them in to an internal list of the aggregate, as to not bloat down that file entirely. Amount of code wont be less, but it will be a little bit easier to keep things ordered. Really not a design solution, more about how to aid the brain in maintaining overview.

Translator/upgrader will blur the visual appearance of the code/system. Don’t know which takes less effort to not mess up.

Any how, let’s say I have event A. I happened to design it (and the system logic) wrongly, but it has it’s part to play. I just realised that for things to actually work I need to add some extra behaviour in the system around that event, i.e. both in the AR that raises it, and in the process that reacts to it (or in the other AR, don’t split hairs). How would that weak serialization be a solution in that case? The system will break when it tries to access properties in the old events, that were never populated at the moment of their inception. That’s what we have the translators for, no?

Creating a new event B on the other hand will require:

  1. a command for the event

  2. a command handler for the command

  3. an eventhandler in the AR

  4. an eventhandler in a processmanager that acts on other ARs as a result of the event

  5. a router for the processmanager

  6. possibly some handler in a read model for that event

  7. probably some additional stuff I forget now

This is not hundreds of lines of codes, but still a few. It’s almost the same procedure for every new event.

Just adding one property to the event, would be so much easier. So setting up translators for every change then. That would eventually result in a range of translators, applying their changes one after another to the passingthrough events.

So event A goes through translator A-Z, each adding a property according to some new logic, that is written for the sole purpose of fetching that property value from somewhere (if possible) and populate the event with it.

If it was not possible to fetch that data (never stored and not possible to derive) the new behaviour must have protective logic to account for these missing values. Would bloat the code a little. I guess that’s a necessary tradeoff then.

Is this the end of the road? Or can this be solved in a better way?