I'm new to saga.
Here a simple scenario :
The whole workflow is :
NEW
-> SUBMITTED
.SUBMITTED
the user can cancel is submission and the order switch back to NEW
. VALIDATED
or REJECTED
. REJECTED
the orginal user must fix his order before put it to VALIDATION again. So I need to avoid that the order can rollback to NEW
when a VALIDATION
is in progress.
My question is, for step 3, is it better to :
thanks
DDD
is about the domain so first you need understand the business needs. So, let's see what are the rules:
The validation process
could take some time and it can be canceled. If it is canceled the order can be submited againThe validation process
could either reject the order or accept the orderThat being said, I would keep separate the two processes (the order creation+creation and the order validation). Also I would keep a status property on the OrderAggregate
that is being used to enforce its invariants. The status can be:
new
: after the order is created or the validation is canceled or order is rejectedsubmitted
: after it is submitted for validationsent
: after it is accepted by the validation process.You should add new states only if you need aditional behavior.
The OrderValidationSaga
would also have an internal status used to keep track of the external responses received from the external services. Let's suppose that we need to use two external services. The status would be an object with two properties: service1IsOk
and service2IsOk
. When any of the services says that the order is invalid then the saga rejects the order regardless of the internal progress and it resets its internal state. When a service says OK then the saga mark it internally as OK then it checks if all the services are OK. If they are OK it tells the aggregate to send the order. Then the aggregate marks the order as sent
and emits an event. If/when the process is canceled, the saga resets its internal state.
Note that if you use CQRS
then all the status changing are done by sending commands and raising events. The saga would subscribe to events and send the appropriate commands to the aggregate.
There is a fine article here.