Konrad
Konrad

Reputation: 7208

Does event store store state?

Theoretically when using event sourcing you don't store "state" but events. But I saw in many implementations that you store snapshots of state in a column in a format like JSON or just a BLOB. For example:

Using an RDBMS as event sourcing storage

The events table has Data column which stores entire object. To me, it's like storing state for that given time when some event occurred.

Also this picture(taken from Streamstone):

enter image description here

It has Data column with a serialized state. So it stores state too but inside an Event?

So how to replay from the initial state then, If I can simply pick some event and access Data to get the state directly.

What exactly is stored inside Data, is it a state of the entire object or it's serialized event?

Let's say I have a person object (in C#)

public class Person
{
    public string Name { get; set }
    public int Age { get; set; }
}

What should my event store when I create a person or change properties like name or age.

When I create a Person I most likely will send something like PersonCreatedEvent with the initial state, so the entire object.

But what if I change Name or Age should they be 2 separate events or just 1? PersonChangedEvent or PersonChangedAgeEvent and PersonChangedNameEvent?

What should be stored in the event in this case?

Upvotes: 0

Views: 1282

Answers (2)

VoiceOfUnreason
VoiceOfUnreason

Reputation: 57257

What exactly is stored inside Data, is it a state of the entire object or it's serialized event?

That will usually be a serialized representation of the event.

One way of thinking about it: a stream of events is analogous to a stream of patch documents. Current state is calculated by starting from some known default state and then applying each patch in turn -- aka a "fold". Previous states can be recovered by choosing a point somewhere in the stream, and applying the patches up to that point.

The semantics of events, unlike patches, tends to be domain specific. So Checked-In, Checked-Out rather than Patched, Patched.

We normally keep the events compact - you won't normally record state that hasn't changed.

Within your domain specific event language, the semantics of a field in an event may be "replace" -- for example, when recording a change of a Name, we probably just store the entire new name. In other cases, it may make sense to "aggregate" instead -- with something like an account balance, you might record credits and debits leaving the balance to be derived, or you might update the total balance (like a gauge).

In most mature domains (banking, accounting), the domain language has semantics for recording changes, rather than levels. We write new entries into the ledger, we write new entries into the checkbook register, we read completed and pending transactions in our account statement.

But what if I change Name or Age should they be 2 separate events or just 1? PersonChangedEvent or PersonChangedAgeEvent and PersonChangedNameEvent?

It depends.

There's nothing wrong with having more than one event produced by a transaction.

There's nothing wrong with having a single event schema, that can be re-used in a number of ways.

There's nothing wrong with having more than one kind of event that changes the same field(s). NameLegallyChanged and SpellingErrorCorrected may be an interesting distinction to the business.

Many of the same concerns that motivate task based UIs apply to the design of your event schema.

It still seems to me like PersonChangedEvent will contain all person properties that can change. Even if they didn't change

In messaging (and event design takes a lot of lessons from message design), we often design our schema with optional fields. So the event schema can be super flexible, while any individual representation of an event would be compact (limited to only the information of interest).

Upvotes: 3

Andreas Gustafsson
Andreas Gustafsson

Reputation: 321

To answer your question, an event that is stored should be the event data only. Not the objects state. When you need to work on your Entity, you read up all the events and apply them to get the latest state every time. So events should be stored with the events data only. (ofc together with AggregateId, Version etc)

The "Objects State" will be the computation of all events, but if you have an Eventlistener that listens to all your published events you can populates a separate ReadModel for you. To query against and use as read only from a users perspective.

Hope it helps!

Updated answer to updated question: Really depends on your model, if you do the update at the same time Age and Name, yes the new age and name values should be stored in a new event. The event should only contain this data "name and age with aggregateId, version etc" The event listener will listen specifically on each event (created, updated etc), find the aggregates read model that you have stored and only update these 2 properties (in this example). For createevent you create the object for the read model.

Upvotes: 1

Related Questions