Handling external events


My Aggregate receives messages from an integration service that deals with some external system. Semantically, these messages are events: they tell the aggregate of what has already happened. I classify them as “external events”.
However, they are targeted at that specific aggregate instance and in that are similar to commands.

The only way I’ve found to have the aggregate process them is by using @CommandHandler annotation. But this just looks wrong because these messages are events.

What does it take to create a custom annotation, e.g. @ExternalEventHandler, that behaves like @CommandHandler?

I apologize in advance if this question has been asked/answered here before: I looked for, and haven’t found the answer.

Thank you very much!

Sorry, an important detail: I am writing in Kotlin, and it seems that it doesn’t allow to extend Java annotations. In Java, this seems to work:

@Target({ElementType.METHOD, ElementType.CONSTRUCTOR, ElementType.ANNOTATION_TYPE})
@MessageHandler(messageType = CommandMessage.class)
public @interface ExternalEventHandler {

Hi Vlad,

Your use case is not uncommon, but I would be careful with being explicit in your Aggregate that those annotated handlers are actually handling events from another system.
The fact that those message are events should be a concern of the integration service alone as it provides the integration between the bounded context of the aggregate and the bounded context of the external system.
Regardless, if you consciously decide to be very specific about the origination point of those messages, your suggested @ExternalEventHandler annotation does the trick.

That’s my two cents on this idea.


Hi Steven,

Thank you very much for the answer.

And, of course, I have a follow up question. In the language of Axon (Axonic?), what term would you use to represent messages that:

  • live in the same context as the Aggregate (the integration service producing them is at the context’s boundary as A/C Layer between the context and the external system)
  • originate outside of the Aggregate (in the integration service)
  • target only this aggregate
  • are, semantically, events: they inform the aggregate of something of interest that happened outside of its boundaries


Hi Vlad,

When it comes to describing a single message, to me it always comes down to deducing whether it’s a command (or command response), event or query (or query response).
From which Bounded Context a message originates or to what Bounded Context it is targeted is, in my opinion, not of importance when describing the message.
The message should within the given context correctly describe what it is for, and that’s that.

Thus, does the message portray something has happened, then it’s an event.

And, if the message describes the intent to perform some operation, it’s a command.
But, if the event originates from another context is not something that event should state, because it is not of importance within the given Bounded Context.

As such, the Axon language (or the people at AxonIQ for that matter) does not use more specific words to describe “an event that originates from another context” than using just that exact sentence.

However, this is a discussion on a meta level of course.
Within your Domain, it might just make perfect sense to give specific meaning to “an event that originates from another context”.
What that name might be however highly depends on your Domain and is thus a question worth asking your Domain experts.

So what I just drafted up is a somewhat lengthy response to state “it depends”.
Regardless, I hope this clarifies things for you Vlad.