Is it ok to have FAT events with event sourcing?

1.1k Views Asked by At

I have recently been building an application on top of Greg Young EventStore as my peristance layer and I have been pondering how big should I allow an event to get?

For example I have an UK Address Aggregate with the following fields

UK_Address
-BuildingName
-Street
-Locality
-Town 
-Postcode

Now I'm building the UI using React/Redux and was thinking should I create a single FAT addressUpdated Event contatining all the above fields?

Or should I Create a event for each of the different fields? and batch them within the client until the Save event is fired? buildingNameUpdated Event, streetUpdated Event, localityUpdated Event.

I'm not sure if the answer is as black and white ask I have asked it what I really would like to know is what conditions/constraints could you use to make the decision?

4

There are 4 best solutions below

0
On BEST ANSWER

You have to bundle al the information together in one event when this data has to be consistent with each other.

So when you update one field of an address you probably get an unwanted address. This will happen when the client has not processed all the events at a certain time due to eventual consistency.

Example: Change address (City=1, Street=1, Housenumber=1) to (City=2, Street=2, Housenumber=2)

When you do this with 3 events and you have just processed one at the time of reading you could get the address: (City=2, Street=1, Housenumber=1).

0
On

If puzzled, give a try to a solution that is easier to implement. I guess "FAT" event will be easier: you will end up spending less time for implementing/debugging/supporting.

It is usually referred as YAGNI-KISS-Occam's Razor principles.

3
On

should I create a event for each of the different fields?

No. The representations of your events are part of the API -- so you want to use spellings that make sense at the level of the business, not at the level of the implementation.

Now I'm building the UI using React/Redux and was thinking should I create a single FAT updateAddress Event containing all the above fields?

You don't need to constrain the data that you send to your UI to match that which is in the persistence store. The UI is just a cached representation of a read model; there's no reason that representation needs to have the same form as what is in your event store.

Consider the React model itself -- your code makes changes to the "in memory" representation of your data, and then the library computes the new DOM and replaces it, which in turn causes the browser to update its view, which in turn causes the pixels on the screen to change.

So taking a fat event from the store, and breaking it into field level events for the UI is fine. Taking multiple events from the store and aggregating them into a single message for the UI is also fine. Taking events from the event store and transforming them into a spelling that the UI will recognize is also fine.

Do you have any comment regarding Arien answer regarding keeping fields that need to be consistent together? so regardless of when your snapshop the current state of the world it would be in a valid state?

I don't believe that this makes sense, and I'm not sure if it is possible in general.

It doesn't make sense, because "valid state" is a write model concern only; events are things that have happened, its too late to vote on whether they are valid or not. For instance, if you deploy a new model, with a new invariant, it still needs to respect the history of what happened before. So you can build a snapshot for that new model, but the snapshot may not be "valid". Too bad.

Given that, I don't think it makes sense to worry over whether each individual event in a commit leaves the snapshot in a valid state.

In particular, if a particular transaction involves multiple entities, it is very likely that the domain language will suggest an event for each entity (we "debit cash" and "credit accounts receivable"). The entities themselves, of course, are capable of changing independently of each other -- it's the aggregate that maintains the balance.

0
On

In theory and I find it to be a good rule of thumb is to have your commands and events reflecting the intent of the user staying true to DDD. You can find a good explanation of the pros and cons about event granularity here: https://medium.com/@hugo.oliveira.rocha/what-they-dont-tell-you-about-event-sourcing-6afc23c69e9a