0

I am working in an event-sourcing architecture and while creating the aggregates I came to an interesting challenge, disclaimer I'm new to this.

I have a UserAggregate encapsulating the logic for commands, the user has a relationship with campaigns but not really owned by user.

Campaigns are created by an admin system, users can accept to participate in campaign. In my understanding there are boundaries between Campaigns and Users and so will be two different services.

UserAggregate contains IEnumerable<AcceptedCampaign> property and a command can be void AcceptCampaign(campaignId) which creates an object AcceptedCampaign and sets the AcceptedCampaign.Status = Accepted and raise an event of UserCampaignStatusChanged. An admin related listener is registered to this event, loads a CampaignAggregate and the admin (human) changes the status of the campaign based on additional event data and raise the event UserAcceptedCampaignStatusAdminChanged.

There's a user related listener now subscribed to the UserAcceptedCampaignStatusAdminChanged event and will change the UserAggregate with the new status using void ChangeCampaignStatus(campaignId, status) which sets the AcceptedCampaign.Status = Approved and raise an event of UserCampaignStatusChanged though and brings us to a cycle between admin <> user listeners but with a relatively easy solution.

My thoughts now are the below.

  • Admin listener will only process UserCampaignStatusChanged with status that is of interest of admin but feels a bit error prone e.g. switch (campaignStatus);
  • Is it OK for UserAggregate to be shared between the microservice and an event subscriber of UserAcceptedCampaignStatusAdminChanged or it breaks Single Responsibility?

I appreciate your input.

1 Answer 1

1

Can Aggregate shared between services?

The short answer is: no.

To ensure consistency, you normally want only a single authoritative representation of an aggregate. That will normally mean that the aggregate is "stored" in one place - for example, in "the database".

So in a way, sharing the authority for an aggregate is analogous to sharing a database with another service. While you might use the same physical appliance, you normally want each service to control its own logical database, and that in turn suggests that sharing is a bad idea.

(Expressing the same idea a slightly different way -- aggregates are closely related to the notion of coarse grained locks. We don't normally want two different services that can lock the same data.)

Normally, what happens in these sorts of cases is further analysis. Possible outcomes include a redesign of the one aggregate into two separate pieces that are each "owned" by a service separately, or a redesign in which one service gets to cache a (possibly stale) copy of the aggregate owned by the other service.

2
  • I understand and it's clear and doesn't even make sense for CampaignsService and UsersService to share UserAggregate, but, It seems that UsersService and UsersProcessManager, the event listener concerned of events that will change the state of users data is coupled and so I'd assume there is no other way. The purpose of having a listener subscribed to events is I guess due to the HTTP REST service process nature that might be unavailable or in sleep (rare case), maybe wrong but event subscriptions feel wrong in a Web API and better implemented as background daemons. Apr 26, 2019 at 3:29
  • Definitely don’t share aggregates and my design solution is to split the aggregate. Apr 26, 2019 at 21:46

Your Answer

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

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