A lightweight, non-blocking, reactive runtime for the Serverless Workflow specification. Use it to load, validate, and execute workflows written in YAML/JSON—or build them programmatically with our Fluent DSL.
- Features
- Modules
- Installation
- Quick Start
- Detailed Walkthrough
- Fluent Java DSL
- Mermaid Diagrams
- Lifecycle Events
- Errors & Auth
- Development
- License
This reference implementation can run workflows consisting of:
Tasks
SwitchSetDoRaiseListenEmitForkFor/ForEachTry(withCatch/Retry)WaitCall- HTTP
- Basic auth
- Bearer auth
- OAuth2 / OIDC auth
- Digest auth (via Fluent DSL)
- OpenAPI
- Function
- gRPC
- HTTP
Run- Container
- Script
PythonJavascript
- Workflow
- Shell
Schema Validation
- Input / Output validation
Expressions
- Input / Output / Export
- Special keywords:
runtime,workflow,task, …
Error Definitions
- Standard & custom error types
Lifecycle Events
Pending,Started,Suspended,Faulted,Resumed,Cancelled,Completed
This SDK is modular by design—pull in only what you need:
-
serverlessworkflow-impl-core Workflow engine & core interfaces. Depends on generated types and CloudEvents SDK.
-
serverlessworkflow-impl-jackson 👉 Most users add this one.
Adds Jackson integration, JQ expressions, JSON Schema validation, and CloudEvents (de)serialization.
Internally, this module is an aggregation of smaller modules to allow part replacement if needed:
- serverlessworkflow-impl-jq JQ expression implementation
- serverlessworkflow-impl-model Jackson model implementation
- serverlessworkflow-impl-validation Schema validation implementation
- serverlessworkflow-impl-lifecycle-events Enable publication of lifecycle events as Json cloud events.
- serverlessworkflow-impl-function Function support.
- serverlessworkflow-impl-template-resolver JaxRS URI template implementation.
- serverlessworkflow-impl-json Json common utilities shared by all modules in this list
-
serverlessworkflow-impl-http HTTP
Calltask handler, based on Jax-RS client -
serverlessworkflow-impl-jackson-jwt Optimized entity converter for Jackson model and OAuth2/OIDC helpers for HTTP calls.
-
serverlessworkflow-impl-openapi OpenAPI support
-
serverlessworkflow-impl-grpc gRPC support
-
serverlessworkflow-impl-script-python Python support
-
serverlessworkflow-impl-script-js Javascript support
-
serverlessworkflow-impl-container Docker container support
There are also companion modules/docs for:
- Fluent DSL (programmatic builder)
- Mermaid (diagramming workflows)
Links below.
<!-- Core + Jackson (YAML, JQ, JSON Schema, CloudEvents) -->
<dependency>
<groupId>io.serverlessworkflow</groupId>
<artifactId>serverlessworkflow-impl-jackson</artifactId>
</dependency>
<!-- Add if you use HTTP Call tasks -->
<dependency>
<groupId>io.serverlessworkflow</groupId>
<artifactId>serverlessworkflow-impl-http</artifactId>
</dependency>
<!-- Add if your HTTP calls require OAuth2/OIDC -->
<dependency>
<groupId>io.serverlessworkflow</groupId>
<artifactId>serverlessworkflow-impl-jackson-jwt</artifactId>
</dependency>implementation("io.serverlessworkflow:serverlessworkflow-impl-jackson")
implementation("io.serverlessworkflow:serverlessworkflow-impl-http") // if using HTTP
implementation("io.serverlessworkflow:serverlessworkflow-impl-jackson-jwt") // if using OAuth2/OIDCRequires Java 17+.
We’ll run a simple workflow that performs an HTTP GET. See the full YAML in examples/simpleGet/src/main/resources/get.yaml.
try (WorkflowApplication appl = WorkflowApplication.builder().build()) {
var output =
appl.workflowDefinition(WorkflowReader.readWorkflowFromClasspath("get.yaml"))
.instance(Map.of("petId", 10))
.start()
.join();
logger.info("Workflow output is {}", output);
}try (WorkflowApplication appl = WorkflowApplication.builder().build()) {
appl.workflowDefinition(WorkflowReader.readWorkflowFromClasspath("get.yaml"))
.instance(Map.of("petId", 10))
.start()
.thenAccept(output -> logger.info("Workflow output is {}", output));
}Example output:
Workflow output is {"id":10,"category":{"id":10,"name":"string"},"name":"doggie",...}
Full examples:
- Blocking: examples/simpleGet/src/main/java/io/serverlessworkflow/impl/BlockingExample.java
- Non-blocking: examples/simpleGet/src/main/java/io/serverlessworkflow/impl/NotBlockingExample.java
We’ll coordinate two workflows—one listens for high temperatures and the other emits temperature events:
listen.yamlwaits for an event withtemperature > 38(non-blocking)emit.yamlemits events using a workflow parameter
Create an application (customize thread pools, etc.). WorkflowApplication is AutoCloseable, so use try-with-resources:
try (WorkflowApplication appl = WorkflowApplication.builder().build()) {
WorkflowDefinition listen = appl.workflowDefinition(WorkflowReader.readWorkflowFromClasspath("listen.yaml"));
WorkflowDefinition emit = appl.workflowDefinition(WorkflowReader.readWorkflowFromClasspath("emit.yaml"));
// Start the listener (non-blocking)
listen.instance(Map.of())
.start()
.thenAccept(out -> logger.info("Waiting instance completed with {}", out));
// Emit a low temperature (ignored)
emit.instance(Map.of("temperature", 35)).start().join();
// Emit a high temperature (completes the waiting workflow)
emit.instance(Map.of("temperature", 39)).start().join();
}You’ll see:
Waiting instance completed with [{"temperature":39}]
Source: examples/events/src/main/java/events/EventExample.java
As shown in previous examples, to start a new workflow instance, first a WorkflowInstance is created from a WorkflowDefinition, specifying the desired input, and then start method is invoked over it. Start method returns a CompletableFuture, which might be used to obtain the output, either synchronously or asynchronously.
Once started, and before it completes, a workflow instance execution can be suspended or cancelled. Once cancelled, a workflow instance is done, while a suspended one might be resumed.
Workflow progress might be recorded into DB. See details
Prefer building workflows programmatically with type-safe builders and recipes? 👉 Docs: https://github.com/serverlessworkflow/sdk-java/blob/main/fluent/README.md
Highlights:
- Chainable builders for
Call HTTP,Listen/Emit,Try/Catch/Retry,Switch,Fork, etc. - Reusable “recipes” (e.g.,
http().GET().acceptJSON().endpoint("${ ... }")) - Static helpers for auth (
basic(...),bearer(...),oidc(...), …) and standard error types.
Generate Mermaid diagrams for your workflows right from the SDK. 👉 Docs: https://github.com/serverlessworkflow/sdk-java/blob/main/mermaid/README.md
Great for docs, PRs, and visual reviews.
Every workflow publishes CloudEvents you can subscribe to (in-memory or your own broker):
io.serverlessworkflow.workflow.*→pending,started,suspended,faulted,resumed,cancelled,completedio.serverlessworkflow.task.*→started,suspended,resumed,cancelled,completed
See impl tests/examples for consuming and asserting on these events.
Errors
- Raise standard errors with versioned URIs (e.g.,
runtime,communication,timeout, …) or custom ones. - Fluent helpers (e.g.,
serverError(),timeoutError()) set both type URI and default HTTP status; override as needed.
Authentication (HTTP Call)
- Basic / Bearer / Digest
- OAuth2 / OpenID Connect (client credentials, etc.)
- Fluent helpers:
basic("user","pass"),bearer("token"),oidc(authority, grant, clientId, clientSecret), …
Prereqs
- Java 17+
- Maven (or Gradle)
Build & Verify
mvn -B clean verifyFormatting & Lint (CI parity)
mvn -B -DskipTests spotless:check checkstyle:checkRun examples
- See
examples/directory for runnable samples.
Apache License 2.0. See LICENSE for details.
Questions or ideas? PRs and issues welcome!