I am wondering how two bounded contexts can communicate in Axon. I have found several references to the support of bounded contexts in Axon but I can’t seem to find a guide on how they interact (on an implementation level).
In my project, we have the case that the creation of an aggregate in bounded context A must trigger the creation of another aggregate in bounded context B. From what I read, I need to create an event handler that listens to the bounded context A AggregateCreatedEvent and dispatches a command to bounded context B. The command handler there creates a bounded context B AggregateCreatedEvent. I can’t use the command gateway for this since I need to communicate with another Axon context, right? How do I send the command?
I found a solution to my problem. Axon Server can act as a distributed message bus which means that an application can dispatch a command that is handled by another application. Combined with a TargetContextResolver as described in this thread the applications can be connected to different contexts.
I stumbled on this by accident and I wish it would be more explicit in the reference guide. I feel like this is an important feature in Axon.
I have decided to introduce explicit ApiCommands which form the public contract between different contexts. A command handler in the receiving context acts as an ACL and translates the ApiCommand into an internal command. Is this the suggested approach to inter-context communication?
TargetContextResolver → something you figured out yourself… this is the configuration to where your messages should go to
MultiStreamableMessageSource and it’s messageSource → this is where your messages come from, meaning your app can listen to more than a single context as well
thank you for linking to the example. The MultiStreamableMessageSource looks interesting but raises a question. Is it desirable that a different context knows about the events of another context? In theory, I can get rid of my event handler and TargetContextResolver in context A and replace them with an event listener in context B. The event listener ingests events from context A which it is interested in and issues commands as required.
This removes the explicit dependency of having to know the exact context where I want to send my commands in context A (i.e., TargetContextResolver). It is also more extensible because I don’t need to change context A if I introduce another event listener in another context. However, a dependency on the event schema of another context is added. I am not sure which I like better. What do you think?