Is there a recommended practice on publishing events/commands?

According to the guide, in command handlers, we only validate the state and publish some event in the end as a form of decision. In event handlers, we change the aggregate state.

According to this answer, I can publish commands in event handlers. What about even sourcing handlers (as I understand, if an aggregate serves command AC, then publishes event AE, then in an event sourcing handler publishes command BC and it fails, then command AC also fails)? And how do I test it? There is no support for testing the behavior of event handlers, so it feels not natural to put logic there.

According to the JavaDoc of AggregateLifecycle#apply, you can also publish events in event handlers.

So, what is the recommended practice to go about these situations and are there any other ways to write code in Axon that I didn’t mention?

There are two kind of Eventhandlers.
EventHandlers that are used for reading an Aggregate back from an Eventstream annotated with @EventSourcingHandler.
You should not publish new Commands from this type of EventHandler, because each time this aggregate is reconstructed the EventHandler will be called and therefore a new event will be published. This results in a lot of duplicated commands from each event in the aggregates history. If I remember correctly Axon even throws an Exception if you try to do this.

The other type of eventhandler is used to react to events that happened and this can be done in multiple ways.
The first one is using an eventhandler on a saga. A saga has state and has a tracking token that keeps track on which events has been processed. Therefore this is a better place to react to events with new commands, because you won’t have the problem of sending commands from events that have been processed a long time ago.
If you don’t need state or complex business decisions you can also use a regular EventHandler. A tracking token keeps track of which events have been processed.
More information about regular eventhandlers can be found here: https://docs.axoniq.io/reference-guide/implementing-domain-logic/event-handling/handling-events

A projection is a less desirable way to send commands based on events, because it recreates state and will produce a lot of duplicate commands when rebuild.

Hope this helps a little

Greezt,
Gideon

Thanks, Gideon!

I just tried starting up my app with events already in the store, placed a logging statement inside the command handler of the command that is published from the sourcing handler. But that statement wasn’t printed, so, I guess, you are mistaken on this one? Doesn’t matter if I publish commands in @EventHandler or @EventSourcingHandler

Hi Sam, Gideon,

I’d like to add that you should take the stance to perform zero blocking operations from within an Aggregate.
Yes, the framework is set up so that you can wire virtually anything in your message handling functions (through Parameter Resolvers), but not any service is suitable to wired in an Aggregate.

When you dispatch a command, the framework will always place a lock on that exact Aggregate instance (through the LockingRepository).
This is done to ensure no concurrent operations occur on a single Aggregate, which is desirable from a consistency constraints perspective.
Added, 9 out of 10 times a Command is directed towards a single Aggregate as well.

Thus, if you’d wire a CommandGateway/CommandBus in an Aggregate to dispatch another command, you will not lock one Aggregate, but two Aggregates.
Additionally, if that new command you dispatch circles back to the Aggregate instances which dispatched, you’re even in bigger sh*t.

Now let me circle back to my zero blocking operations argument.

The fact your Aggregate is locked is why I state you should not perform any blocking operations from within an Aggregate.
Doing so, will only extend the period of the lock, decrease the number of operations you could perform on an Aggregate within a given time frame.
This can thus greatly slow down your entire system (trust me, I’ve been there).

So, Sam, I’d take Gideon’s guidance on this.
Segregate the concerns and let your Aggregate solely deal with it’s own consistency boundary.
If you want to deal with dispatching follow up commands as a reaction to certain events, then that logic should be placed in a different component (e.g. a Saga or regular Event Handling Component).
It is not the responsibility of your Aggregate to communicate with other Aggregates through commands.

Hope this helps you out Sam.

Cheers,
Steven

Thanks, Steven!

So, if I take all operations I do as a reaction to an event from the @EventSourcingHandler and put them in an @EventHandler that would be enough? Do I have to put this @EventHandler in a separate class or can I do this in the same aggregate?

About Saga, I thought it is only appropriate to use Saga if you have a long-running operation like an item delivery or something.

Hi Sam,

You should have your @EventHandler annotated method in a different component then your Aggregate.
As soon as it lives in your Aggregate, Axon will tie it to the life cycle of that Aggregate Instance, which you do not want when you’re reacting to an event with other operations.

The when or when not to use a Saga is, in my eyes, always a ‘it depends’ kinda request.
It’s use to model Complex Business Transaction between Aggregates/Bounded-Context which contain a notion of time.
So, if the operation you like to perform corresponds to that, then you could go for a Saga.

If it doesn’t, for example because there is no notion of time involved or it is simply not complex, then a regular Event Handling Component would be sufficient.

Cheers,
Steven

I have XAggregate and XGroupAggregate (from this question). XUpdatedEvent in XAggregate should cause a list of UpdateXCommand to be dispatched (to update other X in the group). But in order to send them, I a list of XAggregate ids (in this group) that is stored in XGroupAggregate.
So, do I understand correctly, that this is the 1 out of 10 case where it is okay to autowire the CommandGateway inside an aggregate (I want to put XUpdatedEvent handler inside XGroupAggregate and dispatch commands from there)? That way I will lock the whole group but that seems ok since I am updating them all.

I guess I would need to put a “propagate” flag inside that event so I don’t create an infinite recursion

Sorry, forgot to mention, that I will actually only propagate this update to a part of the group. So while I lock 100% of X, I will only touch 10-80% of them during locking.

Another solution I see is that I could send a PrepareXPropagateCommand which would return (publish an event with) ids of the X that I need to send UpdateXCommand for. That way I could put this logic outside of any aggregate and avoid locking but introduce more messages.

  1. Is it better to simply return result from the command or publish an event with the result?
  2. I feel that the more messages I define the more complex my system is, do you feel the same?
  3. Which approach of these two should I favor in your opinion?

Sorry again for storming with posts, but I have another point. UpdateXCommand involves an API call to one of many third-party systems. So, since I am dealing with multiple systems I cannot control, it is probably not a very good idea to lock and wait for a response from each of the ones I have on my list. The more systems I wait for, the greater the risk of one of them being down.
So I will pick PrepareXPropagateCommand for now, but still very eager to hear another perspective!

Also, I could use repository instead of PrepareXPropagateCommand, but the JavaDoc says it might be a design smell if I use it to query an aggregate…

Hi Sam,

Sam, I think you need to rethink either the scope of your Aggregate Root or start using Sagas.
Sagas, as pointed out, are there to delegate operations between different Aggregate Roots.

This ties in to what you’re stating with the different types of Aggregates.

Next to that, you could also enlarge the size of your Aggregate Root, meaning that you contain both aggregates in the same group.
You are thus expanding the consistency boundary in that way, but this omits the need of dispatching off putting “Prepare commands” which do not mean a thing in your domain, for example.

Whether a Saga or a bigger Aggregate Root is the way to go wholly depends on your domain.
As I am not the expert of your domain, I’d be hard pressed to give you the exact path to take.
As always, it depends.
What might be valuable if your struggling with question like this, is to follow the training AxonIQ provides in regards to CQRS, DDD, ES and anything Axon Framework and Server.

Lastly, I would always stay clear from performing long-running operation inside an Aggregate.
Dispatching a Command should be regarded as a long-running operation, thus is a massive no in my book.

Hope this helps.

Cheers,
Steven

Thank you for your answer!

Sagas, as pointed out, are there to delegate operations between different Aggregate Roots.

This does sound a lot like my situation! But it does not correlate much with documentation, perhaps, would be beneficial to others if it was mentioned there?

I cannot use a bigger Aggregate Root, because the client that uses this system does not know anything about groups and only operates on the X. As we know, to access aggregate member, I have to specify the aggregate root id, which I don’t have at the API level, that’s why they are split. I will definitely give a try using Saga!

Regarding the “no-no” for command dispatching inside an aggregate, I have also addressed your comments and removed all of them except for one case described here, where I assign the X to its group inside X constructor.