Sponsor: Do you build complex software systems? See how NServiceBus makes it easier to design, build, and manage software systems that use message queues to achieve loose coupling. Get started for free.
Events are an API in an Event-Driven Architecture. Treat them that way. Often, events are thought of as either domain events or integration events. But there’s more of a distinction to be made. Here’s a slightly different way of thinking about events that can impact your system long-term using an Event-Driven Architecture.
YouTube
Check out my YouTube channel, where I post all kinds of content accompanying my posts, including this video showing everything in this post.
Domain vs Integration
I think the most common distinction people make if they are making a distinction, is between domain and integration events.
Domain events are often thought of as things that have occurred that a business cares about within a logical boundary. Don’t get me wrong, developers can do developer things, and more technical events can emerge as domain events because they happen within a logical boundary.
Integration events are considered to be used when they communicate and notify other systems, subsystems, logical boundaries, etc. In practice, it seems integration events are being used less to notify that a business concept has occurred and more for data distribution. If that sounds familiar, check out my post Event-Driven Architecture lost its way.
Both share the same purpose: to notify that something has occurred. However, how you define them, their characteristics, and their utility is often different.
Inside vs Outside
A different way of thinking about the distinction is between inside and outside.
Inside events are happening within a logical boundary. Outside events are to communicate outside a logical boundary.
Events are an API, and you should treat them like one.
An application programming interface (API) is a way for two or more computer programs or components to communicate with each other.
https://en.wikipedia.org/wiki/API
If you treat them like an API, private/internal events can mutate and evolve because you control the consumer (itself). You can make breaking changes and only break yourself.
Public Events are contracts (API) to outside consumers. You will often have different versioning strategies for the two if you don’t want to break your consumers with breaking changes.
If you treat them that way, you’ll start to see how using outside events to distribute data often leaks internal private implementation details.
However, if you treat both of them as derived from business concepts that occurred, consumers often want to consume them for different reasons.
Granular vs Summary
Private events are often more granular as they describe very specific things that have occurred within that logical boundary. Outside consumers often wouldn’t want to consume these events because they are too granular. They are looking for larger, impactful events that have occurred, which often contain a summary/aggregate of smaller granular events.
For example, the first three events (product received and shipped) might be too granular for outside consumers. However, they want a summary of what a Stock Count (Inventory Adjusted) event provides.
If the stock count occurs frequently enough to satisfy consumers, this event might become a public event.
Meaning when some private events occur, there is some translation done to that event or to generate a public event that is an aggregate or summary event used as a public event.
Stability
If you’re focusing on business concepts, some are stable and at the core of your domain and aren’t likely to change. You might consider exposing those as both private and public. Just realize the trade-offs you’re making when deciding that. My example of a Stock Count (Inventory Adjustment) might fit that need as both an public and private event.
So instead of thinking of domain events and integration events, rather think of your events as an API and if they are a public or private API.
They still have business concepts related to them, but the consumers and what they care about will be different. Private events are consumed within the same logical boundary and might care about their granularity.
Events are an API
Public events often have very different reasons for consuming events and often times want more of a summary or aggregate of events.
Language matters. Consumers of public events have a completely different context than your own. Public events allow you to not leak out how you may internally think about certain concepts unique to that boundary. Rather you can define public events that are more tailored and named to outside contexts.
Join CodeOpinon!
Developer-level members of my Patreon or YouTube channel get access to a private Discord server to chat with other developers about Software Architecture and Design and access to source code for any working demo application I post on my blog or YouTube. Check out my Patreon or YouTube Membership for more info.