DDD - Managing "User" entity between aggregates

86 Views Asked by At

I'm trying to rewrite monolith app onto a modular monolith using DDD and hexagonal architecture. Tried to extract three modules (aggregates) at first: "Shared", "User" and "Article".

As I understood it correctly, no dependency should be created between "User" and "Article". However, both of them can use stuff from the "Shared" module.

So here's the thing... The "Article" module have Article entity which is in relation to the User entity. It's the creator of a particular article, from a DDD perspective. There will be even more modules like that having relation to the User entity as being an author or an owner of a resource.

How should it be implemented? Should it be moved to the "Shared"? Unfortunately, couldn't find any particular resource. Github mostly contains projects with a single aggregate and without such things as User entity.

2

There are 2 best solutions below

0
phduarte On

I have been seeing different ways to solving these kind of problems. You can create a Shared aggregate, no one can say it is wrong. But, I consider the best solution is you create a Person (or People) aggregate where you can have an PersonEntity (or AuthorEntity) that is related to ArticleEntity, no problem have relations between Aggregates but I suggest you try to create relations only between aggregate roots.

It's the Eric Evans blue book's sample

Note that Voyage is a AggregateRoot from the Aggregate Voyage and it have a relation with the AggregateRoot Location of the Location aggregate.

0
Huholoman On

You can reference other AggregateRoots using identities. You definitely dont want to have shared Aggregates between multiple AggregateRoots.

The DDD way is to not share any AggregateRoot (or Aggregate) between modules and to have different AggregateRoots in each module. Lets say UserAggregateRoot in UserModule and AuthorAggregate(Root) in ArticleModule. If you need just to reference Author in Article module, you dont need AuthorAggregate(Root), you can have just his identity, lets say AuthorIdentity.

Now if you need more data, for example his full name, the most idiomatic DDD ways is to duplicate data. When UserAggregateRoot is created, you need to propagate changes to other modules. This is usualy done with domain events/event streaming.

Another way is to export some API between modules, usualy public provider service and anticorruption layer, which maps original AggregateRoot (UserAggregateRoot) to AggregateRoot from current module (ArticleAggregateRoot).

As first solution duplicates data and is a bit more complicated, I believe second solution will be better fit for you as it is easier. Downside of it is it couples modules, which should be avoided.