You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: README.md
+7-5Lines changed: 7 additions & 5 deletions
Original file line number
Diff line number
Diff line change
@@ -8,7 +8,7 @@ Provides the Java API for the [Serverless Workflow Specification](https://github
8
8
With the SDK you can:
9
9
10
10
* Read workflow JSON and YAML definitions
11
-
* Write workflow definition in JSON and YAML format.
11
+
* Write workflow definitions in JSON and YAML formats.
12
12
* Test your workflow definitions using the reference implementation.
13
13
14
14
@@ -29,6 +29,7 @@ Note that 6.0.0.Final, which will be the one for specification version 0.9, is s
29
29
30
30
| SDK Version | JDK Version |
31
31
| :---: | :---: |
32
+
| 7.0.0 and after | 17 |
32
33
| 5.0.0 and after | 11 |
33
34
| 4.0.x and before | 8 |
34
35
@@ -76,9 +77,9 @@ There are, roughly speaking, two kind of users of this SDK:
76
77
### Implementing your own runtime
77
78
78
79
For those ones interested on implementing their own runtime, this SDK provides an easy way to load an in memory representation of a given workflow definition.
79
-
This memory representation consist of a hierarchy of POJOS directly generated from the Serverless Workflow specification [schema](api/src/main/resources/schema/workflow.yaml), which ensures the internal representation is aligned with the specification schema. The root of the hierarchy is `io.serverlessworkflow.api.types.Workflow` class
80
+
This in-memory representation consists of a hierarchy of POJOS directly generated from the Serverless Workflow specification [schema](api/src/main/resources/schema/workflow.yaml), which ensures the internal representation is aligned with the specification schema. The root of the hierarchy is `io.serverlessworkflow.api.types.Workflow` class
80
81
81
-
####Reading workflow definition from JSON/YAML source
82
+
### Reading workflow definition from JSON/YAML source
82
83
83
84
You can read a Workflow definition from JSON/YAML source:
84
85
@@ -122,7 +123,7 @@ try (InputStream in = new FileInputStream("simple.yaml")) {
122
123
123
124
For additional reading helper methods, including the one to read a workflow definition from classpath, check [WorkflowReader](api/src/main/java/io/serverlessworkflow/api/WorkflowReader.java) class.
124
125
125
-
####Writing workflow definition to a a JSON/YAML target
126
+
### Writing workflow definition to a JSON/YAML target
126
127
127
128
Given a Workflow instance, you can store it using JSON or YAML format.
128
129
For example, to store a workflow using json format in a file called `simple.json`, you write
@@ -136,5 +137,6 @@ try (OutputStream out = new FileOutputStream("simple.json")) {
136
137
For additional writing helper methods, check [WorkflowWriter](api/src/main/java/io/serverlessworkflow/api/WorkflowWriter.java) class.
137
138
138
139
### Reference implementation
139
-
See Reference implementation [readme](impl/README.md).
140
+
141
+
The reference implementation provides a ready-to-use runtime that supports the Serverless Workflow Specification. It includes a workflow execution engine, validation utilities, and illustrative examples to help you quickly test and deploy your workflows. For details on usage, configuration, and supported features, see [readme](impl/README.md).
Install [Maven](https://maven.apache.org/install.html) (if using Maven)
45
+
Install [Gradle](https://gradle.org/install) (if using Gradle)
46
46
47
47
### Dependencies
48
48
49
-
One of the goals of the reference implementation is to maintain the number of dependencies as lower as possible. With that spirit, a modular approach has been followed, letting the users decide, depending on their workflows nature, which dependencies should be include.
50
-
51
-
In practical terms, this means a separation between the core part and additional dependencies that should be explicitly included if your workflow is interacting with an external service that communicated using a particular technology supported by the specification (at this moment, just HTTP). The intention of this is to avoid adding dependencies that you do not really need (for example, when gRPC call will be implemented, if we were adding the gRPC stack to the core dependencies, you wont be able to get rid of it even if none of your workflows use it)
49
+
This implementation follows a modular approach, keeping dependencies minimal:
50
+
- The core library is always required.
51
+
- Additional dependencies must be explicitly included if your workflow interacts with external services (e.g., HTTP).
52
+
This ensures you only include what you need, preventing unnecessary dependencies.
52
53
53
54
#### Maven
54
55
@@ -58,7 +59,7 @@ You always need to add this dependency to your pom.xml `dependencies` section:
Quick version is intended for impatient users that want to try something as soon as possible.
92
+
The quick version is intended for impatient users who want to try something as soon as possible.
95
93
96
-
Detailed version is more suitable for those users interested on a more thoughtful discussion of the API.
94
+
The detailed version is more suitable for those users interested in a more thoughtful discussion of the API.
97
95
98
96
### Quick version
99
97
100
-
For a quick introduction, we are going to use a simple workflow [definition](../examples/simpleGet/src/main/resources/get.yaml) that performs a get call.
98
+
For a quick introduction, we will use a simple workflow [definition](../examples/simpleGet/src/main/resources/get.yaml) that performs a get call.
101
99
We are going to show two ways of invoking the workflow:
102
100
- blocking the thread till the get request goes through
103
101
- returning control to the caller, so the main thread continues while the get is executed
104
102
105
-
In order to execute the workflow, blocking the thread till the http request is completed, you should write
103
+
In order to execute the workflow, blocking the thread till the HTTP request is completed, you should write
@@ -126,9 +124,12 @@ In order to execute the workflow, without blocking the calling thread till the h
126
124
.thenAccept(node -> logger.info("Workflow output is {}", node));
127
125
}
128
126
```
129
-
When the http request is done, both examples will print a similar output
127
+
When the HTTP request is done, both examples will print a similar output
128
+
130
129
131
-
`Workflow output is {"id":10,"category":{"id":10,"name":"string"},"name":"doggie","photoUrls":["string"],"tags":[{"id":10,"name":"string"}],"status":"string"}`
130
+
```shell
131
+
Workflow output is {"id":10,"category":{"id":10,"name":"string"},"name":"doggie","photoUrls":["string"],"tags":[{"id":10,"name":"string"}],"status":"string"}
132
+
```
132
133
133
134
You can find the complete java code [here](../examples/simpleGet/src/main/java/NotBlockingExample.java)
134
135
@@ -138,15 +139,19 @@ To discuss runtime API we are going to use a couple of workflow:
138
139
-[listen.yaml](../examples/events/src/main/listen.yaml), which waits for an event reporting a temperature greater than 38
139
140
-[emit.yaml](../examples/events/src/main/emit.yaml), which emits events with a certain temperature, specified as workflow parameter.
140
141
141
-
A brief summary of what we are trying to do. We will start listen.yaml, which will complete when it receives an event with the proper temperature, but it wont block the main thread while waiting for it. Then, we will send an event with a lower temperature, that will be ignored. And finally, we will send an event with a greater temperature, that will complete the waiting workflow.
142
+
Here is a summary of what we are trying to do:
143
+
144
+
- The listen.yaml workflow waits for an event (not-blocking).
145
+
- We send an event with a low temperature (ignored).
146
+
- We send an event with a high temperature (completes the workflow).
142
147
143
-
The first step is to create a [WorkflowApplication](core/src/main/java/io/serverlessworkflow/impl/WorkflowApplication.java) instance. An application is an abstraction that allow customization of different aspect of the workflow execution (for example change the default `ExecutorService` for thread spawning)
148
+
The first step is to create a [WorkflowApplication](core/src/main/java/io/serverlessworkflow/impl/WorkflowApplication.java) instance. An application is an abstraction that allows customization of different aspects of the workflow execution (for example, change the default `ExecutorService` for thread spawning)
144
149
145
-
Since `WorkflowApplication` implements `Autocloseable`, we better use a try...finally block, ensuring any resource that might have been used by the workflow is freed when done.
150
+
Since `WorkflowApplication` implements `Autocloseable`, we better use a **try-with-resources** block, ensuring any resource that the workflow might have used is freed when done.
Once we have the application object, we use it to parse our definition examples. To load each workflow definition, we use `readFromClasspath` helper method defined in [WorkflowReader](api/src/main/java/io/serverlessworkflow/api/WorkflowReader.java) class.
154
+
Once we have the application object, we use it to parse our definition examples. To load each workflow definition, we use the `readFromClasspath` helper method defined in [WorkflowReader](api/src/main/java/io/serverlessworkflow/api/WorkflowReader.java) class.
150
155
151
156
```java
152
157
WorkflowDefinition listenDefinition =
@@ -155,9 +160,9 @@ Once we have the application object, we use it to parse our definition examples.
A [WorkflowDefinition](core/src/main/java/io/serverlessworkflow/impl/WorkflowDefinition.java) object is immutable and therefore threadsafe. It is used to execute as many workflow instances as desired.
163
+
A [WorkflowDefinition](core/src/main/java/io/serverlessworkflow/impl/WorkflowDefinition.java) object is immutable and, therefore, thread-safe. It is used to execute as many workflow instances as desired.
159
164
160
-
To execute a workflow, we first create a [WorkflowInstance](core/src/main/java/io/serverlessworkflow/impl/WorkflowInstance.java) object (the initial status is PENDING) and then invoke `start` method on it (the status is changed to RUNNING). `start` method returns a [CompletableFuture](https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/CompletableFuture.html), which we use to indicate that a log message should be printed when the workflow is completed.
165
+
To execute a workflow, we first create a [WorkflowInstance](core/src/main/java/io/serverlessworkflow/impl/WorkflowInstance.java) object (its initial status is PENDING) and then invoke the `start` method on it (its status is changed to RUNNING). The`start` method returns a [CompletableFuture](https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/CompletableFuture.html), which we use to indicate that a log message should be printed when the workflow is completed.
@@ -166,15 +171,15 @@ To execute a workflow, we first create a [WorkflowInstance](core/src/main/java/i
166
171
.thenAccept(node -> logger.info("Waiting instance completed with result {}", node));
167
172
```
168
173
169
-
The next line will be executed as soon as the workflow execution starts waiting for events to arrive, moment at which control is returned to the calling thread. Therefore, we can execute another workflow instance while the first one is waiting.
174
+
As soon as the workflow execution reach the point where it waits for events to arrive, control is returned to the calling thread. Since the execution is not blocking, we can execute another workflow instance while the first one is waiting.
170
175
171
-
We are going to send an event with a temperature that does not satisfy the criteria, so the listen instance will continue waiting. To pass parameters to the workflow instance that sends the event, we use a regular Java `Map`. Notice that, since we want to wait till the event is published before executing the next line, we call `join` after `start`, telling the `CompletableFuture` to wait for workflow completion.
176
+
We will send an event with a temperature that does not satisfy the criteria, so the listen instance will continue waiting. We use a regular Java `Map` to pass parameters to the workflow instance that sends the event. Note that since we want to wait till the event is published, we call `join` after `start`, telling the `CompletableFuture` to wait for workflow completion.
0 commit comments