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 HelloWorkflow class directly.

  • helloWorkflow.startInstance() executes the workflow without blocking the HTTP thread, returning a Mutiny Uni<WorkflowInstance>.

  • We transform that running instance into our custom Message record 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:

  1. Press d in the terminal where Quarkus is running to open the Dev UI in your browser (usually http://localhost:8080/q/dev).

  2. Find the Quarkus Flow card and click the Workflows link.

  3. 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 Flow subclasses at build time and makes them injectable as standard CDI beans.

  • You can safely expose workflows through normal Quarkus REST endpoints using non-blocking Uni types.

  • 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.