Question

I'm working on an application (using Onion Architecture) and I want to have good log of entities' changes.

I'm struggling to find any good examples of what are the best practices - and I want to avoid bad architecture decisions at the beginning of my project.

Let's say I have few Entities (Aggregates in fact): Customer, Product, Cart. This entities are persisted in following tables: Customers, Products and Carts.

These entities produce such events: CustomerCreated, CustomerDeleted, ProductCreated, ProductPriceChanged, CartCreated, CartProductAdded etc.

Question is:

Should I have single table (single event log store) for all my entities, e.g. named DomainEvents?

Or is it better to have single table log per entity, e.g. CustomersLog, CartsLog and ProductsLog.

I'm personally in favor for the latter, because it is in accordance to SRP, and I believe will make log reading much faster (e.g. we can have INDEX on Id in Logs tables and we know that this Id represents given entity).

Was it helpful?

Solution

Since a domain event may affect several aggregates, the event log shall be managed at the level of the domain. It's up to the event consumers to see how to change the states.

Remark: I have avoided to use "table", because tables belong to the implementation and not the domain design: depending on your ORM, events may stored in several tables if there are subtypes and single table inheritance cannot be used. What's important here is that it's at the level of the domain and not at the level of aggregates.

This is fully in line with SRP: The domain event log shall log the events of the domain. And every entity shall process the events that are relevant to it. Event consumers are a kind of observers of the event log. But domain events should in principle (at least, according to Evans) be managed separately from system events, because these are not relevant for the domain.

Domain events are meant to be published for all those who need them. If you would decentralize your event log at the level of the aggregates, you'd have a serious issue with separation of concerns: every aggregate or entity that causes events to be fired would have to know where to find the relevant event log. And this kind of combinatorial explosion is exactly what event logs are meant to avoid. Not even mentioning the dependency nightmare and the principle of least knowledge.

Licensed under: CC-BY-SA with attribution
scroll top