Devman
Devman

Reputation: 310

How to handle relationships between aggregate roots in resolvejs

I'm having trouble figuring out how to handle some basic stuff around relationships between aggregate roots in resolvejs. The basic question is how do I handle the integrity of relationships? To do so, it seems like you need knowledge of both sides at the same time, but that doesn't seem to be allowed in the write side.

Heres the setup: I am trying to build a user management tool and I have two aggregate roots, User and Organisation. I need to allow both to exist independently of each other and define an access relationship between them (i.e. a user can have access to any number of organisation).

If the relationship belongs to the User, I can create a create a command like grantAccessToOrganisation on the User aggregate which takes an organisationId but this raises a couple questions. How do I make sure that the organisationId provided is real one? It seems like it needs to happen in the command handler but since the command belongs to the User aggregate, I don't have access to the Organisation aggregate. Also, how should I handle when an organisation gets removed? It seems like that should have a side effect on all users who have access to it but I don't seem to have a good way of making that query on the write side.

Upvotes: 2

Views: 91

Answers (1)

Roman Eremin
Roman Eremin

Reputation: 1451

Try not to think of aggregate as an "entity" in traditional systems. Choose aggregate root as a transactional and consistency boundary.

This means that all commands to the given aggregate are sequental, its state is consistent, meaning you can be sure that your command is applied to expected aggregate state and no chages is being done by another user or process.

As an extreme example, you can even have a single aggregate "System", and the whole system state will be accessible to you. But this mean the size of the state will be enourmous, and each command will lock the whole system.

So choose your aggregate large enough to control its transactions and small enough not to block other transactions.

In your example, I can guess that User is more about identity, login, profile, avatar - things like that. It can live without knowledge of Organisation and access rights to it. Organisation is the aggregate that deals with access rights and changing access rights is a transaction that affect the single organisation.

So I would send grantAccess command to the Organisation, not to the user in your example. But of course it depends on other requirements, and I could be wrong here.

Also, there always will be some inter-aggregate business rules that can be implemented with saga. An example would be a rule that if User login is disabled, its access rights are removed after 30 days. Saga is a long-running business transaction that can affect several aggregates.

Upvotes: 2

Related Questions