Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Inter-aggregate communication

I currently have a single event stream per aggregate root and twoaggregate roots, Room and RoomType.

The behavior of a Room depends on what RoomType it is. In order to separate both aggregates, The RoomType is just represented as a roomTypeId in the Room aggregate. A change of RoomType is represented by a RoomTypeChanged event.

The RoomTypes can be managed separately and need to be in a different aggregate.

Now consider the following use case:

When a user invalidates a RoomType, all Rooms that have that Roomtype should switch to a fallback RoomType.

I have thought of several approaches, but all of them seem to be problematic:

  1. Have an event listener listen for a RoomTypeInvalidated-event, and send a SwitchToFallbackRoomType on all Room-aggregates that have that Roomtype. How would I do this though? There's no way to know which aggregates have that Roomtype unless I access my readmodel, which seems incorrect. Even if I were to load all aggregates, there's no way to load only the aggregates of that type as I can't load a subset of all streams (using geteventstore).

  2. When reapplying the RoomTypeChanged-events to the Room aggregate, instead of just applying it, do a check to see whether that RoomType still exists, but then again, how would I know which RoomTypes exist (I'd be in the same situation as 1, but inverted)? Also, it seems wrong to put in logic on reapplying events, they should just represent state changes I think.

How would you solve this?

like image 745
Kenneth Avatar asked Nov 09 '22 19:11

Kenneth


1 Answers

We are working with the same issue, also rooms and roomtypes. The solution you are having problems reaching is probably mapped from the relational where this is a non issue. It's hard and confusing to think start thinking behavioral in an otherwise very data-driven field. I think the to solve the problem you have to challenge the proposed solution.

When re-thinking it, we ended up with aggregates like RoomAssignment and RoomAllocationSchedule, and discovered that RoomType is mostly used to communicate room-features to external channels / OTA.

Modelling the behavior we need really helps (since the consistency bounderies starts to make sense), instead of modelling data and trying to enforce relational consistent behavior on it...

When we really need consistency across aggregates, we model a process-manager/saga that in itself is transactionally consistent, and message the aggregates. As such, we have a "RoomAssignmentDirector" aggregate, that makes sure that a room is allocated for a roomstay before it is assigned to the roomstay etc.

Hope it helps.

like image 126
Julian Avatar answered Dec 24 '22 04:12

Julian