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 aggregate
- v1.payments.failed→ A payment failure occurred within the payments domain
- v1.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 authorised
- v1.conversion.trade.settled→ A specific trade within a conversion was settled
- v1.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 settled
- v1.order.items.shipped→ Multiple items in an order were shipped
- v1.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.