Integrate multiple Bounded Contexts

Hi,

I wanted to get some insights on the current best practices when it comes to different bounded contexts interacting with each other. As an example, I want to use the following situation:

The bounded context Employees deals with the complete lifecycle of an employee within an organization. This BC contains the aggregates Employee and Qualification. Qualifications might be assigned to employees. Trivial commands for each aggregate might be:

Employee:

  • RegisterEmployeeCmd
  • AssignQualificationToEmployeeCmd
  • RemoveQualificationAssignmentCmd
  • ArchiveEmployeeCommandCmd

Qualification:

  • CreateQualificationCmd
  • DeleteQualificationCmd

The second BC is called DutyPlanning. This BC contains the aggregates Worker, DutyQualification, and Duty. A worker is someone who is allowed to be assigned to duties. All employees of an organization are also workers. In order to be allowed to be assigned to a duty, the worker must fulfill the minimum qualification of the duty.
DutyQualifications are identical to the qualifications in the BC Employees.

My questions mainly focus on how to keep the BCs in sync and how to implement it in Axon Framework. I have looked at this repository which shows an example of how to achieve this. Here sagas are used to send commands and receive events between BCs.

(1) Do we consider the public commands and events of a BC as its API? I feel that depending on the event schema of another BC might be problematic. How could an ACL mitigate this and how would this ACL be implemented?

In the case of the Qualifications in my example, the two BCs need to be kept in perfect sync regarding changes to the Qualification aggregate.

(2) Is this pattern common/desirable and how could this be implemented? Using sagas seems overkill in this scenario because no state is required. It’s just a matter of sending the appropriate commands to the DutyPlanning BC after an event occurred. External events handlers could be used for this. In which BC would I place these handlers?

Feel free to raise your own questions and expand on my simple example. I highly appreciate any input on this topic :slight_smile:

Hi Daniel,

Since you don’t need state, a saga might indeed be overkill. What you could do is to listen to events from one BC, and use them to trigger commands to another BC. Would that work in your case?

You might optionally need a query to target the correct aggregates in the other BC.

Hi Gerard,

I am mainly looking for best practices. Is it common practice to listen to events in the BC that owns the event and issue commands to other BCs? What other patterns exist?

What could an ACL look like?

The ACL could just look/map to some of the events it needs. Indeed since it’s also used outside of the BC, changes should be made with causion. A way to make clear which which events are clear to use in other BC’s is to put them in a separate package/module. Another option is to use integration events to communicate across BC’s.

How would integration events look like?

Just the bare minimum, so that changes are less likely. Something like WorkerQualified with just the worker if and the qualification id/name, and maybe when the qualification is valid. Ideally you never need to change this event.