Event-Driven Architecture: How I Name Events (A Practical Guide With Examples)
24 Feb 2025Getting event names right in event-driven architecture and Domain-Driven Design (DDD) is essential for clarity, consistency, and scalability. A key decision is using singular or plural terms in event names.
Here's how I approach it, with examples and reasoning to help you make the best choice.
1. Plural for Collections
Example: v1.payees.created
When an event relates to a collection of entities, the domain should be plural. This clarifies that the event belongs to a broader category and aligns with DDD aggregate roots.
Examples:
v1.payees.created
→ A new payee was created within the payees aggregatev1.payments.failed
→ A payment failure occurred within the payments domainv1.users.registered
→ A user was registered in the users domain
2. Singular for Processes
Example: v1.transaction.authorised
If the event describes a business process, workflow, or single entity, use singular to avoid confusion with collections.
Examples:
v1.transaction.authorised
→ A single transaction was authorisedv1.conversion.trade.settled
→ A specific trade within a conversion was settledv1.authentication.failed
→ A single authentication attempt failed
3. Plural for Sub-Entities
Example: v1.conversion.trades.settled
When an event relates to sub-entities within a domain, pluralization helps differentiate them from the main domain.
Examples:
v1.conversion.trades.settled
→ Multiple trades within a single conversion were settledv1.order.items.shipped
→ Multiple items in an order were shippedv1.invoice.payments.processed
→ Multiple payments related to an invoice were processed
4. Versioning at the Beginning
Example: v1.domain.event
Best Practice: Always place the version number at the beginning to make versioning immediately visible and to facilitate version-based routing and filtering.
🚫 Bad Example: payments.failed.v1
✅ Good Example: v1.payments.failed
Why Version First?
Placing the version at the beginning offers several advantages:
- Immediate visibility: Version information is the first thing you see
- Easier filtering: Systems can quickly filter or route by version without parsing the entire event name
- Clearer version transitions: Makes it easier to identify different versions of the same event type
- Consistent with API versioning: Aligns with common API versioning practices
Additional Guidelines
Aggregate Naming in DDD:
Aggregates in DDD are typically singular (e.g., Order), but event topics use plural names (e.g., v1.payments.failed
).
Clarity vs. Rigidity:
Conventions should adapt to domain needs. For example: v1.conversions.trade.settled
might be valid for process collections.
Event Payload Context:
Plurality in event names doesn't dictate entity count. v1.payments.failed
could reference a single payment failure.
Recap
- Plural for collections:
v1.payees.created
,v1.payments.failed
- Singular for processes:
v1.transaction.authorised
,v1.conversion.trade.settled
- Plural for sub-entities:
v1.conversion.trades.settled
,v1.order.items.shipped
- Version at the beginning:
v1.domain.event
Following these naming conventions will make your event-driven architecture structured, scalable, and aligned with domain modelling principles.