I am evaluating the use of Axon as part of the implementation of a new application.
Such application will eventually be one of the choreographed services required to automate a distributed collaborative process.
Having read some of the literature on DDD and the Axon documentation, I am struggling to understand the rationale that lead to separation of aggregates and sagas.
Hence, I am not sure on how to best use the two components.
To my understanding, it is responsibility of the aggregate to maintain the consistency of the state of entities contained within it. In my case, the root of the aggregate would be the process itself and state would be held in the root and its children entities (@EventSourcedMember). Changes of state are caused by execution of commands and notified to the outside world via business events.
So far so good (I think) until I would need to integrate with external services and that should be done using a saga.
A saga (I apologise for the over simplification) is a selective listener. Its responsibility to react on events it has been associated with and broadcast commands accordingly.
The problems I see with such approach are the following:
- Any non trivial saga will have to be stateful so that historical/state information can be used to decide what to do when an event is received (e.g. commit or rollback an operation, splitting or aggregate events, etc.). Inevitably the saga and the aggregate state will overlap in one or more points leading to a loss of cohesion as responsibility is no longer segregated.
- Added complexity. In order to handle external events, sagas have to be implemented to act as proxies to the aggregates.
Would all the above be simplified if events were to be delivered to the aggregate directly? Am I missing something fundamental in my reasoning?