1

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).

1 Answer 1

1

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.

9
  • How about I want to audit the aggregate? Is the DomainEvents good source for that? Or rather separate tables, e.g. CustomersAuditLog would be better? Secound thought - yes, I know 'table' is implementation - however ultimately it has to be persisted; wouldn't such table be too heavy? Commented Jun 13, 2020 at 15:33
  • 1
    @MaciejPszczolinski DBMS are build to handle huge volumes. So if you need to persist the data it should not be an issue. If it is, you have strategies to cope with it, deleting older events that are no longer needed (including for audit).
    – Christophe
    Commented Jun 13, 2020 at 16:01
  • @MaciejPszczolinski Suppose I have an event OrderedProductShipped: the same event would require an update of Product (inventory) and an update of the Order (item status/parcel tracking). But it's one and the same event. Now if you go for event sourcing, you'd still use an event store to persist the events. This store should allow you to query by aggregate and entity. Of course, when processing the events in the first place, you may for performance reasons decide to duplicate some data or make some snapshots.
    – Christophe
    Commented Jun 13, 2020 at 16:31
  • I don't want event sourcing (too complex for my needs). All I need is event log/audit. I want to know what is the history (mutations) that led to the current state of entities. The event OrderedProductShipped I would place in both OrdersLog and ProductsLog exactly because it is a mutation of both, that let to their current state. OrderedProductShipped can change OrderId=111 and ProductId=222. Having single DomainEvents store, it would be hard to query "get me all events of OrderId 111". Wouldn't it? Commented Jun 13, 2020 at 17:43
  • @MaciejPszczolinski One reason more to to have one event log: for audit purpose, query it for the relevant objects; you then have a single source of the truth. I mean answering questions such as “give me all events for order 111” is a basic functionality of an event store. You just need an object type and an object identifier. If the leading ERP manages huge volumes of change events this way, why wouldn’t it work for you?
    – Christophe
    Commented Jun 13, 2020 at 17:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.