Event Sourcing: About using VOs or scalars in the Domain Events

Something often discussed when implementing Event Sourcing is whether or not one should use Value Object’s or simple scalar values inside the Domain Events.

While this is discussed in this thread, I wanted to share my own experience on the subject.

On a project for which we are currently implementing CQRS + ES, that question was heavily discussed.

We concluded that using only simple messages with only scalar values was the good choice for us and for the following reasons:


Having VOs makes the process of serializing and deserializing the events really more complicated and that definitely adds an overhead.

For this project we wanted JSON as serialization format because it’s much easier to read for a human being and definitely much easier to debug. But that’s not the only reason as I will explain later.

Serializing a complex object graph to JSON implies to have some sort of a mapping strategy, especially for the deserialization process. Whatever the strategy you implement, this requires a really performance-killer processing.

Domain Events are considered safe and consistent

Domain Events are created by the aggregates themselves. At this point, every business domain rules already have been validated.

It’s important for us to force the use of Value Objects for what is exposed as a public API and for encapsulating the business rules to keep the domain consistent. They are (VOs) also useful for modeling some complex behavior inside the domain.

But once you validated all the rules, there is no reason for building your domain events with the same VOs you use in your aggregates. At least from the domain consistency point-of-view. The domain events are immutable and once they are written in a stream there is no mechanism allowing them to be written again. So they always are consistent.

Domain Events are messages and should be universally understandable

In a distributed system, we like to consider Domain Events as like any message.

We chose the JSON format because we want them to be universally understandable. A projection is not necessarily coming from your original application. You can imagine having other systems, which are not written using the same programming language, being interested in what happened in your domain. Having events serialized in a standard format and containing only simple scalar values facilitates communication between different part of the system.

The benefice from having VOs in domain events is not worth the cost it implies

That’s our conclusion on this.

At first I blindly didn’t want to get rid of them, because I’m still sometimes obsessed with having a full POO approach like a wayward kid. I like auto-completion in my IDE, I like well designed objects, and I like the beauty of Value Objects.

But if I think about it, objectively, that’s a personal issue.

I tried to find some arguments for keeping them, I really did, but I couldn’t compete because the cons definitely beat me.

I’d be happy to heard some good arguments in favor of the VOs, so I could tell “See, I told you!”, so don’t hesitate!