Event serialization and value objects
One of the important parts of creating an event sourced application is to ensure that you can always read your event streams. It seems simple enough, but it is a problem, especially for large applications that undergo refactoring or domain changes.
The basic idea is to store events in a structure that's easy to access and migrate if the need should arise. EventFlow, like many other event sourced systems, stores its events using JSON.
Making pretty and clean JSON
You might wonder "but, why?", and the reason is somewhat similar to the reasoning behind semantic URLs.
Consider the following value object used to validate and contain usernames in an application.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
|
First we do some cleanup and re-write it using EventFlows
SingleValueObject<>
.
1 2 3 4 5 6 7 8 9 10 |
|
Now it looks simple and we might think we can use this value object directly in our domain events. We could, but the resulting JSON will look like this.
1 2 3 4 5 |
|
This doesn't look very good. First, that extra property doesn't make it easier to read and it takes up more space when serializing and transmitting the event.
In addition, if you use the value object in a web API, people using the API will need to wrap the properties in their DTOs in a similar way. What we would like is to modify our serialized event to look like this instead and still use the value object in our events.
1 2 3 |
|
To do this, we use the custom JSON serializer EventFlow has for single
value objects called SingleValueObjectConverter
on our Username
class like this.
1 2 3 4 5 6 7 8 9 10 11 |
|
The JSON converter understands the single value object and will serialize and deserialize it correctly.
Using this converter also enables to you replace e.g. raw string
and
int
properties with value objects on existing events as they will be
"JSON compatible".
Note
Consider applying this to any classes that inherit from Identity<>
.