What About Using Structured Naming for Event-Driven Messaging?
20 Nov 2024It's a well-known adage that naming things is hard.
In event-driven architectures, a consistent naming convention is essential for scalability, communication, collaboration and maintainability.
At the moment, I'm architecting a new event-driven solution, and I planning to adopt a Structured Naming
approach for event types.
In this post I'll share my thoughts on this approach and its benefits.
Recommended Practice: Embedding Metadata in Event Payloads
It’s a widely recommended practice to include metadata directly within the event payload.
This metadata provides essential context about the event, such as its type, domain, and service, in addition to the data payload itself.
{
"detail": {
"metadata": {
"id": "01HXHMF28A94NS7NSHC5GM80F4",
"version": "1",
"timestamp": "2020-04-28T07:20:20Z",
"domain": "order",
"service": "order-service",
"type": "order-placed"
},
"data": {
"user_id": "123456",
"order_id": "1234567890123",
"restaurant_id": "123456789",
"currency": "USD",
"total": "42.42"
}
}
}
In this example, the type
field within the metadata specifies the event as order-placed
.
While this method provides the necessary context, it can lead to challenges in event routing and subscription management, especially if you’re using NATS, where wildcards offer flexibility and agility.
For instance, if consumers need to subscribe to all events related to orders, they may have to manage subscriptions manually for each type (order-placed
, order-updated
, etc.).
Why Consider a Structured Naming Approach?
The Structured Naming approach organises event names in a structured, dot-separated format. This structure mirrors the natural categorisation of events, enabling intuitive grouping, routing, and filtering by using dots (.
) as separators.
Example of Structured Event Naming
Using a structured naming approach, events related to orders could be organised like this:
order.created
order.updated
order.deleted
Here, the prefix order
denotes the domain or entity, while the suffix (created
, updated
, deleted
) specifies the verb. This structure allows consumers to easily subscribe to domain event types, such as all events under order.*
.
Consistency is Key
Keeping naming patterns predictable and consistent is critical to reducing cognitive load and avoiding confusion. For instance: For instance:
-
use a single separator style (
order.created
) and avoid mixing styles likeorder-created
andorder_created
in the same system. -
Adhering to a clear and consistent format ensures event names remain instantly recognisable.
Benefits of the Structured Naming Approach
-
Improved Clarity
The structured naming convention includes both the event’s domain and action, making it easier to understand the purpose and intent of an event at a glance.
-
Efficient Subscription Management
Consumers can use wildcard subscriptions to receive a broader set of events. For example, subscribing to order.*
captures all events related to orders, such as order.created
and order.updated
.
-
Scalability
As the system grows, adding new event types within a domain becomes seamless. You can introduce new events like order.canceled
or user.profile.updated
without overhauling existing subscription logic.
-
Sharding Capabilities
A structured naming convention can facilitate sharding by grouping related events with common prefixes (e.g. order.*
or user.*
).
This simplifies routing related events to the same shard, improving performance and resource allocation.
Adopting a Structured Naming Pattern
When adopting a structured naming approach, splitting by domain helps communicate intent and related actions.
-
Domain or Entity
Represents the primary category, such as
order
,user
, orpayment
. -
Action or Event Type
Specifies the exact type of event, like
created
,updated
, ordeleted
.
Example of Structured Event Names
-
User Events
user.registered
user.logged_in
user.profile.updated
-
Payment Events
payment.initiated
payment.completed
payment.failed
This structure provides a consistent and organised approach to naming events, which should prove especially beneficial as systems scale and require more event types across multiple domains.
Versioning Strategy
When versioning events, Version in Path strategy aligns well with wildcard subscriptions. For instance:
-
Versioned Event Types
order.v1.created
order.v2.updated
user.v1.profile.updated
This approach allows services to listen to specific versions or broader categories, such as order.v2.*
, giving flexibility in routing as schemas evolve.
Use Cases
-
Microservices Architectures
In a microservices environment, services often respond to events from multiple domains. A structured naming convention allows services to subscribe to broader categories efficiently. For example, subscribing to user.*
simplifies setup by reducing the need to enumerate all event types.
-
Event Sourcing
In event-sourced systems, where state is reconstructed from historical events, a structured naming scheme enables systematic grouping and processing of events by category.
AntiPatterns and Potential Drawbacks of Structured Naming
As with all things, there is a danger of overuse and misuse that could lead to complexity and challenges:
-
Initial Implementation Effort
Standardising event names across teams requires upfront planning and governance.
-
Complexity in Deep Naming Structures
Overly deep structures (e.g.,
order.process.payment.canceled
) can reduce clarity. Keeping structures simple and well-documented avoids this pitfall.
Conclusion
I think a structured naming convention for events can offer a straightforward, organised approach that enhances clarity, scalability, and efficiency in event-driven systems.
Have you tried this approach? I'd love to hear about anything I've missed or overlooked, as well as any challenges, advantages, or pitfalls you've encountered.