Naming of events - make source system explicit in name or not

Hi all, I am curious about your thoughts/experiences concerning event naming and the inclusion of the source of the event in the name or not. I am currently in a project where we are thinking about the best way to go here. Suppose we have a GiftCardCreatedEvent and this event can be created by different systems. Would it be wise to make the name of these different sources explicit in the event name? In our case, we have reason to believe that these events would be handled differently depending on the source system. So, given that this is the case, a more specific name looks feasible. On the other hand, this might have some downsides as well, e.g. the number of event types that projections need to handle gets larger, the domain might get more complex to reason about etc.
Other options that we consider are including a source attribute in the event (but that would mean some projections would need to process all events, and discriminate between events in the handler itself) or using inheritance/event hierarchy (but for example, we don’t want to introduce instanceof checks all over the place).

1 Like

Hello and welcome Rob!

Not having any knowledge of your actual domain I’ll stick to the gift card domain leaving event sourcing aside for a moment.

The GiftCardCreatedEvent informs everyone interested that a gift card was created. If I was to split that into GiftCardCreatedBySystemOneEvent and GiftCardCreatedBySystemTwoEvent would that be two different events? I would argue that in the gift cards domain they would not be. Both still inform about the same fact “a gift card was created” but via differently worded messages. In that particular case it would probably make more sense to add a createdBy field in the event and have the event handlers use it to decide how to handle the situation.

That said, an event called SomeoneCalled may be too generic and may not have a precise meaning in a given domain. Such name emphasises the importance of the actor but at the same time it does not explicitly define it. For example ColleagueCalled may be conceptually different event than say CustomerCalled in the given domain. While it may be possible do establish who called based on the message sender or the payload of the message, it’s likely a poor model of the domain. In such case it may be wise to use more explicit events instead.

At the end it’s all about modelling the domain in way that makes sense for the given software system.

1 Like

I would keep the name as the GiftCardCreatedEvent to be honest. As @milendyankov also points out, are they really different events? If they are, then you are speaking of distinct bounded contexts likely, both with their own idea of what the creation of a gift card means. Thus likely also with different contents of those events.

If the source system is valuable information to carry on the GiftCardCreatedEvent, you could go for a field in the event. Or, you could add it as meta data to the message.

Note by the way that Axon uses the fully qualified class name of a class as the payloadType. This payloadType is stored/published together with your event. Furthermore, two GiftCardCreatedEvent class’ in distinct projects would likely have different fully qualified class names. Thus, making them different events from the perspective of Axon. It Is important to take this into account if you need to revamp this thought to an actual solution.

That’s my 2 cents. Hope it helps.

1 Like

Thank you for the explaination. Would sign everything you wrote. Just a thing that helped me a lot to judge on that.

There is a strong misconception on the word “event” if you take event-streaming systems (like Kafka) and event-sourcing systems like Axon.

In event-streaming you identify your event by a “namespace” and a “name” and publish it via pub/sub bus to everyone who is interested. It is your public API. Back to Java namespace is a package and name is your local class name. Having a JSON representation and a registry your would solve it differently. An additional element of freedom is usually a topic. So in this world you either separate by topics or maintain a governance about strict naming of your events by making sure your maintain your package correctly.

In event-sourcing systems, the event is not a public API. it is used inside of your bounded context only and has a meaning inside it. It is used for persistence of your aggregates. You actually never want to distribute your internal implementation-specific message serving synchronization of your command and query model to the outer world. So if you want to use events for communication between context, these are not your domain events from the event store, but other events. People call them milestone events or pivotal events, since they are used to communicate the state change BETWEEN bounden contexts. And regarding the naming of those events, see event-streaming above…

To answer your question: your domain model should have a concept of a fact that occurred, like GiftCardCreated. This is a combination of a concept of GiftCard and Created describing the state. Stay by your language and name the class exactly like this. For convenience reasons you might want to add Event in the end…

My 5 cents…