Modeling Events
Names
Name them and their properties according to the Ubiquitous Language
If an Event is the result of executing a command on an Aggregate, the name is usually drived from the command executed.
The Event name states was occurred (past tense) in the Aggregate after the operation succeeded.
When Publishing Events from Aggregates, it is important that the name reflects the past nature of the occurrence.
Properties
Timestamp when the Event occurred (e.g.
occurredOn
)Consider including whatever would be necessary to trigger the Event again.
This would include the Identity of the Aggregate associated to the Event and any involved Aggregates.
We might also include the properties of parameters that caused the Event (if they are useful).
Aggregate state transition values could be helpful to subscribers.
Most Events will have a constructor that permits only full state initialization, along with a read-only accessors for each property.
It may be necessary to provide additional state if subscribers require more than the indication of the Event's cause.
Helps subscribers to avoid querying back on the Aggregate from which the Event was published.
With Aggregate Characteristics
Sometimes Events are designed to be created by direct request from clients.
This is done in response to a request that is NOT the direct result of executing behavior on an Aggregate.
When this happens, Events can be modeled as an Aggregate and retained in its own Repository without removal.
Events modeled this way are part of the model's structure.
They are not just a record of some past occurrence.
The event is still immutable but may be assigned a generated, unique Identity.
When modeled this way, the Event can be published via messaging infrastructure after successful persistence.
Example: Client could call a Domain Service to create the Event, add to the Repo, and publish over messaging.
With this approach, the Repository and messaging infrastructure should be backed by the same persistence infrastructure to guarantee both happen succesfully.
After successful persistence, an async process would forward the Event to a queue, topic, or actor.
Identity
It may be necessary to distinguish events from another. What if they need to be compared?
The Event's name/type and props, and timestamp may be enough to distinguish it from others.
However, Unique Identity may be necessary when Events are published outside the local Bounded Context.
When messages are delivered more than once, the identity can be used for deduplication by the Messaging infrastructure and/or Consumer.
Last updated