Lab 1 – Hello Flow & Dev UI
In this first lab, you will set up your environment, write a minimal workflow using the Java DSL, and experience the Quarkus Flow developer tooling.
You will:
-
Create a Quarkus app and add the Quarkus Flow extension.
-
Write a workflow using the Java DSL.
-
Invoke it via a reactive REST endpoint.
-
Inspect the auto-generated Mermaid diagram in the Quarkus Dev UI.
1. Create the Quarkus project
If you don’t have a project yet, use the Quarkus CLI to generate a new application with Jackson REST support:
quarkus create app org.acme:hello-flow --extension=rest-jackson
cd hello-flow
Next, add the Quarkus Flow extension to your project:
quarkus extension add io.quarkiverse.flow:quarkus-flow
(If you are not using the CLI, you can manually add the quarkus-flow dependency to your pom.xml).
2. Create a minimal workflow
Workflows in Quarkus are simply Java classes that extend Flow.
Create a HelloWorkflow.java class. This workflow builds a simple sequence with one task that sets a greeting message into the global context and returns it.
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 it through REST
Because Quarkus Flow is non-blocking, it integrates perfectly with Quarkus’s reactive REST layer.
Create a REST resource that injects your workflow bean and starts an instance. Notice how we use a simple Message record to serialize the workflow output into a clean JSON response.
package org.acme;
public record Message(String message) {
}
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());
}
}
Key points:
-
The resource injects the
HelloWorkflowclass directly. -
helloWorkflow.startInstance()executes the workflow without blocking the HTTP thread, returning a MutinyUni<WorkflowInstance>. -
We transform that running instance into our custom
Messagerecord before returning it to the user.
4. Run in dev mode
Start Quarkus in development mode:
./mvnw quarkus:dev
Open a new terminal window and test the endpoint:
curl http://localhost:8080/hello-flow
You should see a JSON output representing the data generated by your workflow:
{"message":"hello world!"}
5. Explore the Quarkus 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.
With dev mode still running:
-
Press
din the terminal where Quarkus is running to open the Dev UI in your browser (usuallyhttp://localhost:8080/q/dev). -
Find the Quarkus Flow card and click the Workflows link.
-
Click on your
hello-workflow.
Here you can:
-
See the auto-generated Mermaid.js diagram showing your exact execution sequence.
-
Trigger new workflow instances directly from the UI using auto-generated input forms.
-
View execution traces and logs.
6. Summary
You have successfully completed Lab 1! You learned that:
-
Quarkus Flow discovers
Flowsubclasses at build time and makes them injectable as standard CDI beans. -
You can safely expose workflows through normal Quarkus REST endpoints using non-blocking
Unitypes. -
The Dev UI gives you a powerful front-end for iterating on and visualizing workflows locally.
Next up: Let’s make this workflow talk to the outside world. Proceed to Lab 2 – Call HTTP & OpenAPI services.