Association between aggregates

Hello,

I have two aggregates where they are related to each other. for e.g

There is a service aggregate and serviceInstance aggregate. Every service has 1 or more service instances associated with it. Where can this relationship be stored?

  1. Option 1 : Maintain a separate db which stores this relationship.
  2. Option 2 : Have a list of instances object stored within service aggregate.
    Any recommendations or suggestion on how this can be handled.

Hi Ajinya,

I don’t know the details regarding this relation, but maybe this could be useful:
https://docs.axoniq.io/reference-guide/implementing-domain-logic/command-handling/aggregate-creation-from-aggregate

Best regards,
Tomek

Hi,

In my opinion, you have two options here:

1. One multi-entity aggregate (https://docs.axoniq.io/reference-guide/implementing-domain-logic/command-handling/multi-entity-aggregates)
In this case, you will have Service as a root of the aggregate which will contain list of ServiceInstances.

2. Two different aggregates Service and ServiceInstance
In this case, you will have two aggregate roots annotated with @Aggregate annotation, and ServiceInstance will have id of the Service as a reference attribute.
This makes your aggregate smaller, and more decoupled. It can be easier to test them smaller, BUT there is an invariant between them that you have to keep.

Invariant: You should not be able to CREATE ServiceInstance with some Service id IF that Service aggregate does not exist.

a) One possible solution to this problem is https://docs.axoniq.io/reference-guide/implementing-domain-logic/command-handling/aggregate-creation-from-aggregate as Tomek mentioned already. This means that command for creating ServiceInstance is actually handled by Service aggregate which has to exist in the first place to be able to handle it.

b) A second possible solution is to use Saga pattern. This will decouple these two aggregates more than in the Solution one, as they will communicate over the messages now (events, commands). In Saga pattern (which can be a regular event handler without Saga annotation) you should be able to handle the creation of ServiceInstance on ServiceInstance aggregate which in turn can publish event that the creation of ServiceInstance has been initiated, This INITIATED event can wake up the Saga to send a command to Service to validate this action. If Service aggregate is fine with this it will publish event noting that Validation Succeded/Failed. Saga will handle this event and publish command to ServiceInstance to mark it as created, finally. Imagine a sequence diagram with three actors: Service - Saga - ServiceInstance

I usually choose 1. Once I see it gets too big I switch to 2a). Once I need more decoupling between them I go for 2b) which is really rare in my case so far, minding that these to aggregates are in the same context/system.

Best,
Ivan

Another option -
Make a External Command handler to handle creation of serviceinstance. In the external command handler load the service by its id. If the service exists , create the serviceinstance otherwise exception.

Please give your suggestions on it. Is my think is correct or not ?

Option suggested by me is actually the extended option of @Ivan as 2c.