Mavlarn
Mavlarn

Reputation: 3883

Using multiple aggregate in one command handler

Provided that I have 2 aggregate, order and customer, and a OrderPayCommand, in the handler, it will check the order status, and check customer balance. If all succeed, it will send an event OrderPaidEvent, which will be handled by Customer aggregate to update balance.

So, how can I check the condition on 2 aggregates in one command handler? So, am I using it in a wrong way?

Upvotes: 0

Views: 1912

Answers (2)

Carlos Verdes
Carlos Verdes

Reputation: 3147

I think the right answer is you have to change your design, the business constraints should be part of a single aggregate, you are doing object oriented programming not ddd.

The idea would be to have two aggregates at least, for example Orders and Payments which will handle Customer orders (the former) and balance and payments (the later).

Payments aggregate will receive one command PayBill { amount, method } and make sure the user has balance first (if not raise an error) and then start the payment (calling a side effect service) then raise the event BillPaid if all was successful or PaymentError { code } if there was an error.

Between the aggregate Payments and Orders you can communicate using events, something like this:

  • Orders send event CustomerSelectedPaymentMethod { amount, method }
  • your controller/router will capture this event and execute command PayBill { amount, method } on Payments aggregate
  • your controller/router will capture result of payment (an event) and call next command on Orders, for example ProceedWithDelivery command if payment was successful or RetryPaymentMethod if we had an error

Upvotes: 0

Steven
Steven

Reputation: 7275

Within the Axon Framework a Command can only ever be handled by one @CommandHandler annotated function. Thus, only one Aggregate will be in charge of handling that action.

If you're orchestrating actions between several aggregates, that typically means you can use a Saga. A Saga in Axon will have associations to several aggregates, which enables you to listen to events from all those aggregates and issue commands to them. This thus enables you to handle certain events like the OrderPaidEvent for example, and upon handling that in your Saga you can issue an AdjustCustomerBalanceCommand to the Customer aggregate you're associated with.

In short: a command is always handled by just one Aggregate/Entity. For orchestrating actions between aggregates, I'd suggest taking a look at the Saga.

Upvotes: 2

Related Questions