Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to manage read requests in an event sourced application

I was asked to do some exploration in event sourcing. my objective is to create a tiny API layer that satisfies all the traditional CRUD operation. I am now using a package called 'sourced' and trying to play around with it (Using Nodejs).

However, I came to realize that the event sourcing is not quite useful when it is used alone. usually, it is coupled with CQRS.

My understanding of the CQRS is, when the UI sends a write command to the server. the app does some validation towards the data. and saves it in the event store(I am using mongoDB), for example: here is what my event store should look like:

{method:"createAccount",name:"user1", account:1}
{method:"deposit",name:"user1",account: 1 , amount:100}
{method:"deposit",name:"user1",account: 1 , amount:100}
{method:"deposit",name:"user1",account: 1 , amount:100}
{method:"withdraw",name:"user1",account1,amount:250}

It contains all the audit information rather than the eventual status. however, I am confused how can I handle the read operation. what if I want to read the balance of an account. what exactly will happen? here are my questions:

  1. If we can not query the event store(database) directly for reading operation, then where should we query? should it be a cache in memory?
  2. If we query the memory. is the eventual status already there or I have to do a replay (or left-fold) operation to calculate the result. for example, the balance of the account 1 is 50.
  3. I found some bloggers talked about 'subscribe' or 'broadcast'. what are they and broadcast to who?

I will be really appreciated for any suggestion and please corret me if my understanding is wrong.

like image 217
nick Avatar asked Sep 04 '17 07:09

nick


People also ask

What is the difference between CQRS and Event Sourcing?

CQRS is implemented by a separation of responsibilities between commands and queries, and event sourcing is implemented by using the sequence of events to track changes in data.

Does CQRS need Event Sourcing?

The current state of the system is determined by processing the events. You may store that result, but only as a cached value, not as the source of truth. Both these patterns are useful, but they do solve different challenges. CQRS is much more common and doesn't need Event Sourcing.

Which is responsible for saving the events for Event Sourcing?

Instead of saving latest status of data into database, Event Sourcing pattern offers to save all events into database with sequential ordered of data events. This events database called event store. Instead of updating the status of a data record, it append each change to a sequential list of events.


2 Answers

Great question Nick. The concept you are missing is 'Projections'. When an event is persisted you then broadcast the event. You projection code listens for specific events and then do things like update and create a 'read model'. The read model is a version of the end state (usually persisted but can be done in memory).

The nice thing is that you can highly optimise these read models for reading. Say goodbye to complicated and inefficient joins etc.

Becuase the read model is not the source of truth and it is designed specifically for reading, it is ok to have data duplication in it. Just make sure you manage it when appropriate events are received.

For more info check out these articles:

  • Overview of a Typical CQRS and ES Application **
  • How to Build a Master Details View when using CQRS and Event Sourcing
  • Handling Concurrency Conflicts in a CQRS and Event Sourced system

Hope you find these useful.

** The diagram refers to denormalisation where it should be talking about projections.

like image 63
Codescribler Avatar answered Oct 30 '22 05:10

Codescribler


You can query the event store. The actual method of querying is specific to every implementation but in general you can poll for events or subscribe and be notified when a new event is persisted.

The event store is just a persistence for the write side that guaranties a strong consistency for the write operations and an eventual consistency for the read operations. In order to "understand" something from the events you need to project those events to a read-model then query the read-model. For example you can have a read-model that contain the current balance for every account as a MongoDB collection.

like image 39
Constantin Galbenu Avatar answered Oct 30 '22 05:10

Constantin Galbenu