Workflows, Now in Axoniq Framework โ€“ Durable Execution with a Full Event-Sourced Audit Trail

Workflows (Preview) are now in Axoniq Framework.

For years, the standard answer to long-running processes in Axon was the Saga. It worked, but it also came with a lot of wiring: state fields, idempotency guards, schedulers, deadline managers, and a dozen event handlers for what is basically one business process. Most of the code had nothing to do with the domain.

Workflows let you write that same process as imperative code, a single execute method. The Workflow engine handles persistence, crash recovery, retries, and timeouts.

@Workflow(startOnEvent = "OrderPlaced", idProperty = "orderId")
public void execute(SimpleWorkflowContext ctx) {
ctx.awaitExecute("reserveStock", inventory::reserve);
ctx.awaitExecute("initiatePayment", payment::initiate,
RetryPolicy.maxRetries(3));
ctx.awaitEvent("awaitConfirmation",
PaymentConfirmed.class,
Duration.ofMinutes(15));
ctx.awaitExecute("shipOrder", shipping::ship);
}

That is the whole order fulfilment process. What used to take multiple handlers and many state fields now fits in one method.

What happens under the hood

Every step the engine executes, writes an event to your event store. awaitExecute("reserveStock", ...) produces a ReserveStockStarted event, runs the action, then writes ReserveStockCompleted. When the workflow hits awaitEvent(...), it writes AwaitPaymentStarted and suspends. When the matching event arrives, it resumes.

This means a few things in practice:

  • If the JVM crashes, the engine replays the event stream on restart and picks up where it left off.
  • Any `@EventHandler` in the application can subscribe to those events. Projections like a shipping dashboard, an SLA monitor, a BPMN tracker, they all work without special integration.
  • When someone asks what happened to order #12847 in March, the answer is in the event store, as a business event.

Most workflow engines discard the intermediate trail after a retention window. Here it stays in the event store permanently.

The API

Five primitives: `execute`, `awaitEvent`, `match`, `setPayload`, and `terminate`. They work with imperative if/for/try-catch, and you can extend `SimpleWorkflowContext` with your own domain verbs so the workflow reads like the business process rather than the infrastructure.

Status

This is a preview release. Core primitives, crash recovery, Spring Boot integration, and the Kotlin DSL are all available now.

Q2 will add hibernating workflows, versioning, and exactly-once delivery guarantees.

Q3 is when we plan general availability release.

If you have a process you have been avoiding to implement, because Sagas felt like too much overhead, Workflows are worth a try.

Links

Get started: Workflows

Full blog post: Workflows, Now in Axoniq Framework

Code sample - Order Fulfillment Workflow: code-samples/order-fulfillment-workflow at main ยท AxonIQ/code-samples ยท GitHub

Playable Workflow simulator: Axoniq is the backend platform for the agentic era

2 Likes