Getting started with Quarkus Flow
Welcome to Quarkus Flow!
Quarkus Flow brings the Serverless Workflow specification natively to Quarkus. It allows you to build durable, event-driven orchestrations and Agentic AI patterns using a highly ergonomic, type-safe Java DSL.
This tutorial shows the shortest path to building, exposing, and visualizing your first Quarkus Flow workflow.
Prerequisites
-
Java 17 or newer.
-
Maven 3.8+ (or the Quarkus CLI).
-
An existing Quarkus project. If you don’t have one, generate it quickly:
quarkus create app org.acme:flow-quickstart cd flow-quickstart
1. Add the dependency
Add the core Quarkus Flow extension to your application.
<dependency>
<groupId>io.quarkiverse.flow</groupId>
<artifactId>quarkus-flow</artifactId>
<version>0.7.1</version>
</dependency>
2. Define your first workflow
Workflows in Quarkus are simply Java classes that extend Flow. At build time, the engine discovers these classes, compiles them into an AST (Abstract Syntax Tree), and registers them as CDI beans.
Create a new Java class. This simple workflow takes an input, sets a greeting message into the global context, and finishes.
package org.acme;
import static io.serverlessworkflow.fluent.func.dsl.FuncDSL.set;
import java.util.Map;
import jakarta.enterprise.context.ApplicationScoped;
import io.quarkiverse.flow.Flow;
import io.serverlessworkflow.api.types.Workflow;
import io.serverlessworkflow.fluent.func.FuncWorkflowBuilder;
@ApplicationScoped
public class HelloWorkflow extends Flow {
@Override
public Workflow descriptor() {
return FuncWorkflowBuilder.workflow("hello")
// setting the workflow context with a map carrying a message.
// it can be translated to JSON as { "message": "hello world!" }
.tasks(set(Map.of("message", "hello world!")))
.build();
}
}
3. Expose the workflow via HTTP
Because Quarkus Flow is non-blocking, it integrates perfectly with Quarkus’s reactive REST layer.
You can inject your HelloWorkflow bean directly into a JAX-RS resource and use the .startInstance() method to execute it.
package org.acme;
import java.util.Map;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import org.jboss.resteasy.reactive.ResponseStatus;
import io.smallrye.mutiny.Uni;
@Path("/hello-flow")
@ApplicationScoped
public class HelloResource {
@Inject
HelloWorkflow hello; // inject the Flow subclass
@GET
@ResponseStatus(200)
public Uni<Message> hello() {
return hello
.startInstance(Map.of()) // convenience on Flow
.onItem()
.transform(w -> w.as(Message.class).orElseThrow());
}
}
(Note: The HelloResource depends on a simple Message record used to serialize the workflow output as JSON):
package org.acme;
public record Message(String message) {
}
4. Run the application and explore the Dev UI
Start Quarkus in development mode:
./mvnw quarkus:dev
Step 1: Test the endpoint
Open a new terminal and invoke the HTTP endpoint you just created:
curl http://localhost:8080/hello-flow
You should see a JSON response containing the message generated by your workflow tasks.
Step 2: See the Magic (The Dev UI)
One of the most powerful features of Quarkus Flow is its visualizer. Because you defined your workflow using a predictable DSL, the engine automatically generates a visual diagram of your logic.
-
Press
din the terminal where Quarkus is running to open the Quarkus Dev UI in your browser. -
Find the Quarkus Flow card and click the Workflows link.
-
Click on your
hello-workflowto see the auto-generated Mermaid.js diagram showing exactly how your tasks execute!
What’s next?
Now that you have the engine running, you can start building real-world orchestrations. Choose your next path:
-
Core Concepts:
-
Data flow and context management — learn how to manipulate data between tasks.
-
Java DSL cheatsheet — a rapid reference for loops, switches, and HTTP tasks.
-
-
Integrations:
-
Call HTTP and OpenAPI services — interact with external REST APIs.
-
Orchestrate LangChain4j Agents — turn your workflows into Agentic AI orchestrators.
-
Use messaging and events — listen and emit CloudEvents over your favorite messaging broker.
-
-
Production Readiness:
-
Configure state persistence — make your workflows durable across crashes and restarts.
-
Fault tolerance and resilience — configure automated retries and circuit breakers.
-