mayqel
mayqel

Reputation: 28

How to correctly persist and present information from multiple aggregates?

I'm creating a selling platform. The core aggregate is called Announcement and it holds references to other aggregates such as Categories, User etc. I am using CQRS approach an event-sourcing solution as storage.

For performance reasons, I decided to store some important details about associated objects (Categories, User) inside the Announcement aggregate along with their ids. My reasoning behind it was that when filtering announcements, I want to simplify the access to those information as much as possible (reduce the number of database joins, allow fancy querying syntax). It was possible, because I included all the required information in the command, which creates an announcement. Generation of a detailed view of an announcement is based on information embedded inside the aggregate. Although it seemed reasonable at first, now I'm having second thoughts.

The considerations that made me think are:

Are the following steps a valid solution for the described problem?

  1. Remove the duplicated information from the Announcement aggregate;
  2. Use a domain event to notify other aggregates about creation of an Announcement;
  3. Let other aggregates publish appropriate events in response to the AnnouncementCreated event; these events may contain additional information about associated objects;
  4. Introduce a multistream projection, which will update itself in response to events from multiple aggregates and produce a complete view of the announcement;

Upvotes: 0

Views: 471

Answers (2)

Maxime Gélinas
Maxime Gélinas

Reputation: 2330

Never design aggregates by thinking of how you will read data. That is against the purpose of CQRS. Aggregates are about commands and business rules not queries. Use events to gather data from multiple aggregates then project the data however you want without affecting your aggregates. This concept is called a "projection".

Upvotes: 3

Levi Ramsey
Levi Ramsey

Reputation: 20561

In general, the only reason to include data in a particular aggregate is if that data affects command validation or if there's some other consistency demand. if information about categories or users isn't qualifying under either reason, then it makes a lot of sense to remove it from the announcement aggregate.

I would probably consider modeling a "categorized and associated announcement" aggregate which is fed by domain events from announcement/category/user aggregates. This could be implemented via the multistream projection from your event store, but I think it's useful to keep that detail separate because there are other ways you could feed domain events from multiple aggregates as commands for a different aggregate (the command implicit in any event is "incorporate this event into your view of the world").

Upvotes: 2

Related Questions