Asynchronous Task
Process a domain event by triggering an asynchronous task or process.
Problem
In a bike rental domain, a renter may register and subsequently go through an onboarding workflow. This workflow is encapsulated as an orchestration that must be launched asynchronously.
Solution
Perform a hand-off in the event handler for the domain event to a separate task or process.
Example
The event model in figure 1 depicts the outlined bike rental scenario in the problem section:

Figure 1 - Modeling asynchronous event processing
A newly registered renter is processed asynchronously by initiating an onboarding workflow.
The particulars of the onboarding workflow are not modeled in this example (only its commencement and completion is shown); typically those details are modeled as a distinct business flow elsewhere in the event model. Awaiting the completion of an asynchronous task or process is outside the scope of this pattern; typically any interested components have to listen for a suitable event, such as OnboardingCompleted in figure 1. This example uses Restate for defining and running external workflows. Other options include Temporal and Dapr Workflow. |
Listing 1 shows a sample workflow definition:
@Workflow
public class OnboardingWorkflow {
@Workflow
public String run(WorkflowContext ctx, RenterDetails renter) {
// This (potentially long-running) process executes the onboarding
// workflow for a renter.
return 'success';
}
}
Listing 1 - Sample workflow definition
Listing 2 shows a possible implementation of the InitiateOnboarding command in an Axon event handler:
@EventHandler
public void on(RenterRegistered evt) {
Client workflowEngine = Client.connect("<Workflow Engine Server URL>");
OnboardingWorkflowClient.fromClient(
workflowEngine,
evt.renterId
).submit(renterDetailsFrom(evt));
}
Listing 2 - Process a domain event by asynchronously launching an external workflow
Ensure that the hand-off is idempotent; in listing 2 the launch and execution of the onboarding workflow will only occur once for each renter (based on the renter identifier), as guaranteed by the workflow engine (Restate). |