mishudark / eventhus

Go - CQRS / Event Sourcing made easy - Go
MIT License
465 stars 92 forks source link

Initialize view model. Retrieve events given aggregate id. #11

Open toesterdahl opened 5 years ago

toesterdahl commented 5 years ago

As I understand a 'canonical' CQRS-ES pattern reading clients are encouraged to maintain there own view models, optimized for their use case. A reading client would subscribe to the event queue and build it's view model based on the events it's receive.

The CQRS-ES pattern does not dictate the nature of this view model:

Keeping a local copy of a single aggregate as well as keeping a syncronized (read only) query db is equally valid use cases from the reading client.

I am going to look at a view model representing a single uniquely identifiable aggregate. It could equally well be a set of such aggregates, the entire DDD, it does not matter. The reading client might join the CQRS-ES entwork at any time, meanting that we don't initially know the state of the aggregate. Looking at the life-cycle of my view-model / aggregate there are the following situations.

  1. When a new aggregate is created. The client can safely assume that it is creating a new unique aggregate. It will issue a new command using a new aggregate id and version 0.
  2. When the aggregate exist in the view model. The next command created will use the existing aggregate id and version.
  3. When the command have failed, indicated an invalid (outdated) version: The client will need to catch up with the history of the aggregate.
  4. When the client have the id of the aggregate but no view-model: The client will need to catch up with the history of the aggregate.

So far I assumed that the aggregate have a unique id that I have. This happens to be safe for the application that I am currenly building. It is also possible that the aggregate can additonally be identified by a natural key that also uniquely identifies the aggregate. The CQRS-ES pattern propose a reading client building an index (mapping natural key to aggregate id) to care for these situations. To care for building the index there is also the following situation.

  1. When the client does not have the aggregate key and can not safely assume that the aggregate does not exist. Look up the aggregate, bootstrap the index: retrieve all aggregates with all events.

For now I am mostly interested in (3.) and (4.). How do the client get all the events of an existing aggregate? The client have the aggregate id, but does not have an up to date view model.

I would want the account example to cover cases (3.) and (4.). How should the client retrieve all (missing) events given an aggregate id?

mishudark commented 5 years ago

Hello, this is a good topic, IMO projections can solve this kind of problems (3 and 4), I'm thinking into create a helper for it, based on the actual behavior used to get the last state of an aggregate

mishudark commented 5 years ago

I'm glad to announce the pre-release of eventhus v2, you can see the progress in branch v2, it contains a better strategy to traceability using a command ID autogenerated, and the new Alert type for errors, that will be published to the interested listeners