Domain events
If you ever read the Blue Book, you'd notice that the Domain Event concept is not mentioned there. Still, years after the book was published, events have become popular, and domain events in particular.
Eric Evans, the author of the Blue Book, has added the definition to his Domain-Design Reference. Let us start with Eric's definition:
When talking about Event Sourcing, we focus on the last bit: "making explicit the events [...], which are associated with state changes." Event Sourcing takes this definition further, and suggests:
We can also cite an article from Medium (a bit controversial one):
Event Sourcing effectively answers this question by giving you a history of all the state transitions for your domain objects, represented as domain events.
So, what this page is about? It doesn't look like a conventional documentation page, does it? Nevertheless, let's see how domain events look like when you build a system with Eventuous.
Oh, that's it? A record? Yes, a record. Domain events are property bags. Their only purpose is to convey the state transition using the language of your domain. Technically, a domain event should just be an object, which can be serialised and deserialized for the purpose of persistence.
Eventuous do's and dont's:
Do make sure your domain events can be serialised to a commonly understood format, like JSON.
Do make domain events immutable.
Do implement equality by value for domain events.
Don't apply things like marker interfaces (or any interfaces) to domain events.
Don't use constructor logic, which can prevent domain events from deserializing.
Don't use value objects in your domain events.
The last point might require some elaboration. The Value Object pattern in DDD doesn't only require for those objects to be immutable and implement equality by value. The main attribute of a value object is that it must be correct. It means that you can try instantiating a value object with invalid arguments, but it will deny them. This characteristic along forbids value objects from being used in domain events, as events must be unconditionally deserializable. No matter what logic your current domain model has, events from the past are equally valid today. By bringing value objects to domain events you make them prone to failure when their validity rules change, which might prevent them from being deserialized. As a result, your aggregates won't be able to restore their state from previously persistent events and nothing will work.