diff --git a/ctk/features/call.feature b/ctk/features/call.feature
index 6ebcfbe2..0db32456 100644
--- a/ctk/features/call.feature
+++ b/ctk/features/call.feature
@@ -15,14 +15,13 @@ Feature: Call Task
namespace: default
name: http-call-with-content-output
do:
- getFirstAvailablePet:
- call: http
- with:
- method: get
- endpoint:
- uri: https://petstore.swagger.io/v2/pet/findByStatus?status={status}
- output:
- from: .[0]
+ call: http
+ with:
+ method: get
+ endpoint:
+ uri: https://petstore.swagger.io/v2/pet/findByStatus?status={status}
+ output:
+ from: .[0]
"""
And given the workflow input is:
"""yaml
@@ -43,13 +42,12 @@ Feature: Call Task
namespace: default
name: http-call-with-response-output
do:
- getPetById:
- call: http
- with:
- method: get
- endpoint:
- uri: https://petstore.swagger.io/v2/pet/{petId}
- output: response
+ call: http
+ with:
+ method: get
+ endpoint:
+ uri: https://petstore.swagger.io/v2/pet/{petId}
+ output: response
"""
And given the workflow input is:
"""yaml
@@ -70,16 +68,15 @@ Feature: Call Task
namespace: default
name: http-call-with-basic-auth
do:
- getSecuredEndpoint:
- call: http
- with:
- method: get
- endpoint:
- uri: https://httpbin.org/basic-auth/{username}/{password}
- authentication:
- basic:
- username: ${ .username }
- password: ${ .password }
+ call: http
+ with:
+ method: get
+ endpoint:
+ uri: https://httpbin.org/basic-auth/{username}/{password}
+ authentication:
+ basic:
+ username: ${ .username }
+ password: ${ .password }
"""
And given the workflow input is:
"""yaml
@@ -99,16 +96,15 @@ Feature: Call Task
namespace: default
name: openapi-call-with-content-output
do:
- getPetsByStatus:
- call: openapi
- with:
- document:
- uri: https://petstore.swagger.io/v2/swagger.json
- operation: findPetsByStatus
- parameters:
- status: ${ .status }
- output:
- from: . | length
+ call: openapi
+ with:
+ document:
+ uri: https://petstore.swagger.io/v2/swagger.json
+ operation: findPetsByStatus
+ parameters:
+ status: ${ .status }
+ output:
+ from: . | length
"""
And given the workflow input is:
"""yaml
@@ -127,15 +123,14 @@ Feature: Call Task
namespace: default
name: openapi-call-with-response-output
do:
- getPetById:
- call: openapi
- with:
- document:
- uri: https://petstore.swagger.io/v2/swagger.json
- operation: getPetById
- parameters:
- petId: ${ .petId }
- output: response
+ call: openapi
+ with:
+ document:
+ uri: https://petstore.swagger.io/v2/swagger.json
+ operation: getPetById
+ parameters:
+ petId: ${ .petId }
+ output: response
"""
And given the workflow input is:
"""yaml
diff --git a/ctk/features/composite.feature b/ctk/features/composite.feature
index aad61fc0..0cc3b799 100644
--- a/ctk/features/composite.feature
+++ b/ctk/features/composite.feature
@@ -12,16 +12,15 @@ Feature: Composite Task
namespace: default
name: composite-sequential
do:
- setRGB:
- execute:
- sequentially:
- setRed:
+ execute:
+ sequentially:
+ - setRed:
set:
colors: ${ .colors + ["red"] }
- setGreen:
+ - setGreen:
set:
colors: ${ .colors + ["green"] }
- setBlue:
+ - setBlue:
set:
colors: ${ .colors + ["blue"] }
"""
@@ -40,19 +39,18 @@ Feature: Composite Task
namespace: default
name: composite-sequential
do:
- setRGB:
- execute:
- concurrently:
- setRed:
+ execute:
+ compete: true
+ concurrently:
+ - setRed:
set:
colors: ${ .colors + ["red"] }
- setGreen:
+ - setGreen:
set:
colors: ${ .colors + ["green"] }
- setBlue:
+ - setBlue:
set:
colors: ${ .colors + ["blue"] }
- compete: true
"""
When the workflow is executed
Then the workflow should complete
diff --git a/ctk/features/data-flow.feature b/ctk/features/data-flow.feature
index 7b06f226..6c92e081 100644
--- a/ctk/features/data-flow.feature
+++ b/ctk/features/data-flow.feature
@@ -12,11 +12,10 @@ Feature: Data Flow
namespace: default
name: output-filtering
do:
- setUsername:
- input:
- from: .user.claims.subject #filters the input of the task, using only the user's subject
- set:
- playerId: ${ . }
+ input:
+ from: .user.claims.subject #filters the input of the task, using only the user's subject
+ set:
+ playerId: ${ . }
"""
And given the workflow input is:
"""yaml
@@ -39,14 +38,13 @@ Feature: Data Flow
namespace: default
name: output-filtering
do:
- getPetById:
- call: http
- with:
- method: get
- endpoint:
- uri: https://petstore.swagger.io/v2/pet/{petId} #simple interpolation, only possible with top level variables
- output:
- from: .id #filters the output of the http call, using only the id of the returned object
+ call: http
+ with:
+ method: get
+ endpoint:
+ uri: https://petstore.swagger.io/v2/pet/{petId} #simple interpolation, only possible with top level variables
+ output:
+ from: .id #filters the output of the http call, using only the id of the returned object
"""
And given the workflow input is:
"""yaml
@@ -67,22 +65,24 @@ Feature: Data Flow
namespace: default
name: non-object-output
do:
- getPetById1:
- call: http
- with:
- method: get
- endpoint:
- uri: https://petstore.swagger.io/v2/pet/{petId} #simple interpolation, only possible with top level variables
- output:
- from: .id
- getPetById2:
- call: http
- with:
- method: get
- endpoint:
- uri: https://petstore.swagger.io/v2/pet/2
- output:
- from: '{ ids: [ $input, .id ] }'
+ execute:
+ sequentially:
+ - getPetById1:
+ call: http
+ with:
+ method: get
+ endpoint:
+ uri: https://petstore.swagger.io/v2/pet/{petId} #simple interpolation, only possible with top level variables
+ output:
+ from: .id
+ - getPetById2:
+ call: http
+ with:
+ method: get
+ endpoint:
+ uri: https://petstore.swagger.io/v2/pet/2
+ output:
+ from: '{ ids: [ $input, .id ] }'
"""
When the workflow is executed
Then the workflow should complete with output:
diff --git a/ctk/features/emit.feature b/ctk/features/emit.feature
index 8954a4c2..4531be46 100644
--- a/ctk/features/emit.feature
+++ b/ctk/features/emit.feature
@@ -12,14 +12,13 @@ Feature: Emit Task
namespace: default
name: emit
do:
- emitUserGreeted:
- emit:
- event:
- with:
- source: https://fake-source.com
- type: com.fake-source.user.greeted.v1
- data:
- greetings: ${ "Hello \(.user.firstName) \(.user.lastName)!" }
+ emit:
+ event:
+ with:
+ source: https://fake-source.com
+ type: com.fake-source.user.greeted.v1
+ data:
+ greetings: ${ "Hello \(.user.firstName) \(.user.lastName)!" }
"""
And given the workflow input is:
"""yaml
diff --git a/ctk/features/flow.feature b/ctk/features/flow.feature
index 705a34b3..cad4a786 100644
--- a/ctk/features/flow.feature
+++ b/ctk/features/flow.feature
@@ -11,15 +11,17 @@ Feature: Flow Directive
namespace: default
name: implicit-sequence
do:
- setRed:
- set:
- colors: '${ .colors + [ "red" ] }'
- setGreen:
- set:
- colors: '${ .colors + [ "green" ] }'
- setBlue:
- set:
- colors: '${ .colors + [ "blue" ] }'
+ execute:
+ sequentially:
+ - setRed:
+ set:
+ colors: '${ .colors + [ "red" ] }'
+ - setGreen:
+ set:
+ colors: '${ .colors + [ "green" ] }'
+ - setBlue:
+ set:
+ colors: '${ .colors + [ "blue" ] }'
"""
When the workflow is executed
Then the workflow should complete with output:
@@ -38,18 +40,20 @@ Feature: Flow Directive
namespace: default
name: explicit-sequence
do:
- setRed:
- set:
- colors: '${ .colors + [ "red" ] }'
- then: setGreen
- setBlue:
- set:
- colors: '${ .colors + [ "blue" ] }'
- then: end
- setGreen:
- set:
- colors: '${ .colors + [ "green" ] }'
- then: setBlue
+ execute:
+ sequentially:
+ - setRed:
+ set:
+ colors: '${ .colors + [ "red" ] }'
+ then: setGreen
+ - setBlue:
+ set:
+ colors: '${ .colors + [ "blue" ] }'
+ then: end
+ - setGreen:
+ set:
+ colors: '${ .colors + [ "green" ] }'
+ then: setBlue
"""
When the workflow is executed
Then the workflow should complete with output:
diff --git a/ctk/features/for.feature b/ctk/features/for.feature
index 43c17e04..0423622f 100644
--- a/ctk/features/for.feature
+++ b/ctk/features/for.feature
@@ -14,13 +14,12 @@ Feature: For Task
namespace: default
name: for
do:
- forEachColor:
- for:
- each: color
- in: '.colors'
- do:
- set:
- processed: '${ { colors: (.processed.colors + [ $color ]), indexes: (.processed.indexes + [ $index ])} }'
+ for:
+ each: color
+ in: '.colors'
+ do:
+ set:
+ processed: '${ { colors: (.processed.colors + [ $color ]), indexes: (.processed.indexes + [ $index ])} }'
"""
And given the workflow input is:
"""yaml
diff --git a/ctk/features/raise.feature b/ctk/features/raise.feature
index 58567530..e7df2459 100644
--- a/ctk/features/raise.feature
+++ b/ctk/features/raise.feature
@@ -11,12 +11,11 @@ Feature: Raise Task
namespace: default
name: raise-custom-error
do:
- raiseComplianceError:
- raise:
- error:
- status: 400
- type: https://serverlessworkflow.io/errors/types/compliance
- title: Compliance Error
+ raise:
+ error:
+ status: 400
+ type: https://serverlessworkflow.io/errors/types/compliance
+ title: Compliance Error
"""
When the workflow is executed
Then the workflow should fault with error:
diff --git a/ctk/features/set.feature b/ctk/features/set.feature
index 6d748ed9..f9cbb64a 100644
--- a/ctk/features/set.feature
+++ b/ctk/features/set.feature
@@ -12,11 +12,10 @@ Feature: Set Task
namespace: default
name: set
do:
- initialize:
- set:
- shape: circle
- size: ${ .configuration.size }
- fill: ${ .configuration.fill }
+ set:
+ shape: circle
+ size: ${ .configuration.size }
+ fill: ${ .configuration.fill }
"""
And given the workflow input is:
"""yaml
diff --git a/ctk/features/switch.feature b/ctk/features/switch.feature
index 01471cc0..f101bef9 100644
--- a/ctk/features/switch.feature
+++ b/ctk/features/switch.feature
@@ -11,29 +11,31 @@ Feature: Switch Task
namespace: default
name: switch-match
do:
- switchColor:
- switch:
- red:
- when: '.color == "red"'
- then: setRed
- green:
- when: '.color == "green"'
- then: setGreen
- blue:
- when: '.color == "blue"'
- then: setBlue
- setRed:
- set:
- colors: '${ .colors + [ "red" ] }'
- then: end
- setGreen:
- set:
- colors: '${ .colors + [ "green" ] }'
- then: end
- setBlue:
- set:
- colors: '${ .colors + [ "blue" ] }'
- then: end
+ execute:
+ sequentially;
+ - switchColor:
+ switch:
+ - red:
+ when: '.color == "red"'
+ then: setRed
+ - green:
+ when: '.color == "green"'
+ then: setGreen
+ - blue:
+ when: '.color == "blue"'
+ then: setBlue
+ - setRed:
+ set:
+ colors: '${ .colors + [ "red" ] }'
+ then: end
+ - setGreen:
+ set:
+ colors: '${ .colors + [ "green" ] }'
+ then: end
+ - setBlue:
+ set:
+ colors: '${ .colors + [ "blue" ] }'
+ then: end
"""
And given the workflow input is:
"""yaml
@@ -55,27 +57,29 @@ Feature: Switch Task
namespace: default
name: switch-default-implicit
do:
- switchColor:
- switch:
- red:
- when: '.color == "red"'
- then: setRed
- green:
- when: '.color == "green"'
- then: setGreen
- blue:
- when: '.color == "blue"'
- then: setBlue
- then: end
- setRed:
- set:
- colors: '${ .colors + [ "red" ] }'
- setGreen:
- set:
- colors: '${ .colors + [ "green" ] }'
- setBlue:
- set:
- colors: '${ .colors + [ "blue" ] }'
+ execute:
+ sequentially:
+ - switchColor:
+ switch:
+ - red:
+ when: '.color == "red"'
+ then: setRed
+ - green:
+ when: '.color == "green"'
+ then: setGreen
+ - blue:
+ when: '.color == "blue"'
+ then: setBlue
+ then: end
+ - setRed:
+ set:
+ colors: '${ .colors + [ "red" ] }'
+ - setGreen:
+ set:
+ colors: '${ .colors + [ "green" ] }'
+ - setBlue:
+ set:
+ colors: '${ .colors + [ "blue" ] }'
"""
And given the workflow input is:
"""yaml
@@ -97,31 +101,33 @@ Feature: Switch Task
namespace: default
name: switch-default-implicit
do:
- switchColor:
- switch:
- red:
- when: '.color == "red"'
- then: setRed
- green:
- when: '.color == "green"'
- then: setGreen
- blue:
- when: '.color == "blue"'
- then: setBlue
- anyOtherColor:
- then: setCustomColor
- setRed:
- set:
- colors: '${ .colors + [ "red" ] }'
- setGreen:
- set:
- colors: '${ .colors + [ "green" ] }'
- setBlue:
- set:
- colors: '${ .colors + [ "blue" ] }'
- setCustomColor:
- set:
- colors: '${ .colors + [ $input.color ] }'
+ execute:
+ sequentially:
+ - switchColor:
+ switch:
+ - red:
+ when: '.color == "red"'
+ then: setRed
+ - green:
+ when: '.color == "green"'
+ then: setGreen
+ - blue:
+ when: '.color == "blue"'
+ then: setBlue
+ - anyOtherColor:
+ then: setCustomColor
+ - setRed:
+ set:
+ colors: '${ .colors + [ "red" ] }'
+ - setGreen:
+ set:
+ colors: '${ .colors + [ "green" ] }'
+ - setBlue:
+ set:
+ colors: '${ .colors + [ "blue" ] }'
+ - setCustomColor:
+ set:
+ colors: '${ .colors + [ $input.color ] }'
"""
And given the workflow input is:
"""yaml
diff --git a/ctk/features/try.feature b/ctk/features/try.feature
index cd5fb272..893f9ff6 100644
--- a/ctk/features/try.feature
+++ b/ctk/features/try.feature
@@ -15,22 +15,21 @@ Feature: Try Task
namespace: default
name: try-catch-404
do:
- tryGetPet:
- try:
- call: http
+ try:
+ call: http
+ with:
+ method: get
+ endpoint:
+ uri: https://petstore.swagger.io/v2/pet/getPetByName/{petName}
+ catch:
+ errors:
with:
- method: get
- endpoint:
- uri: https://petstore.swagger.io/v2/pet/getPetByName/{petName}
- catch:
- errors:
- with:
- type: https://serverlessworkflow.io/dsl/errors/types/communication
- status: 404
- as: err
- do:
- set:
- error: ${ $err }
+ type: https://serverlessworkflow.io/dsl/errors/types/communication
+ status: 404
+ as: err
+ do:
+ set:
+ error: ${ $err }
"""
And given the workflow input is:
"""yaml
@@ -56,22 +55,21 @@ Feature: Try Task
namespace: default
name: try-catch-503
do:
- tryGetPet:
- try:
- call: http
+ try:
+ call: http
+ with:
+ method: get
+ endpoint:
+ uri: https://petstore.swagger.io/v2/pet/getPetByName/{petName}
+ catch:
+ errors:
with:
- method: get
- endpoint:
- uri: https://petstore.swagger.io/v2/pet/getPetByName/{petName}
- catch:
- errors:
- with:
- type: https://serverlessworkflow.io/dsl/errors/types/communication
- status: 503
- as: err
- do:
- set:
- error: ${ $err }
+ type: https://serverlessworkflow.io/dsl/errors/types/communication
+ status: 503
+ as: err
+ do:
+ set:
+ error: ${ $err }
"""
And given the workflow input is:
"""yaml
diff --git a/dsl-reference.md b/dsl-reference.md
index 64d3beb7..5631d019 100644
--- a/dsl-reference.md
+++ b/dsl-reference.md
@@ -66,7 +66,7 @@ A [workflow](#workflow) serves as a blueprint outlining the series of [tasks](#t
| document | [`document`](#document) | `yes` | Documents the defined workflow. |
| input | [`input`](#input) | `no` | Configures the workflow's input. |
| use | [`use`](#use) | `no` | Defines the workflow's reusable components, if any. |
-| do | [`map[string, task]`](#task) | `yes` | The [task(s)](#task) that must be performed by the [workflow](#workflow). |
+| do | [`task`](#task) | `yes` | The [task](#task) that must be performed by the [workflow](#workflow). |
| timeout | [`timeout`](#timeout) | `no` | The configuration, if any, of the workflow's timeout. |
| output | [`output`](#output) | `no` | Configures the workflow's output. |
| schedule | [`schedule`](#schedule) | `no` | Configures the workflow's schedule, if any. |
@@ -94,7 +94,7 @@ Defines the workflow's reusable components.
|:--|:---:|:---:|:---|
| authentications | [`map[string, authentication]`](#authentication) | `no` | A name/value mapping of the workflow's reusable authentication policies. |
| errors | [`map[string, error]`](#error) | `no` | A name/value mapping of the workflow's reusable errors. |
-| extensions | [`map[string, extension]`](#extension) | `no` | A name/value mapping of the workflow's reusable extensions. |
+| extensions | [`map[string, extension][]`](#extension) | `no` | A list of the workflow's reusable extensions. |
| functions | [`map[string, task]`](#task) | `no` | A name/value mapping of the workflow's reusable tasks. |
| retries | [`map[string, retryPolicy]`](#retry) | `no` | A name/value mapping of the workflow's reusable retry policies. |
| secrets | `string[]` | `no` | A list containing the workflow's secrets. |
@@ -143,22 +143,22 @@ use:
petStoreOAuth2:
oauth2: my-oauth2-secret
extensions:
- externalLogging:
- extend: all
- before:
- call: http
- with:
- method: post
- endpoint: https://fake.log.collector.com
- body:
- message: "${ \"Executing task '\($task.reference)'...\" }"
- after:
- call: http
- with:
- method: post
- endpoint: https://fake.log.collector.com
- body:
- message: "${ \"Executed task '\($task.reference)'...\" }"
+ - externalLogging:
+ extend: all
+ before:
+ call: http
+ with:
+ method: post
+ endpoint: https://fake.log.collector.com
+ body:
+ message: "${ \"Executing task '\($task.reference)'...\" }"
+ after:
+ call: http
+ with:
+ method: post
+ endpoint: https://fake.log.collector.com
+ body:
+ message: "${ \"Executed task '\($task.reference)'...\" }"
functions:
getAvailablePets:
call: openapi
@@ -169,37 +169,39 @@ use:
parameters:
status: available
secrets:
- - my-oauth2-secret
+ - my-oauth2-secret
do:
- getAvailablePets:
- call: getAvailablePets
- output:
- from: "$input + { availablePets: [.[] | select(.category.name == "dog" and (.tags[] | .breed == $input.order.breed))] }"
- submitMatchesByMail:
- call: http
- with:
- method: post
- endpoint:
- uri: https://fake.smtp.service.com/email/send
- authentication: petStoreOAuth2
- body:
- from: noreply@fake.petstore.com
- to: ${ .order.client.email }
- subject: Candidates for Adoption
- body: >
- Hello ${ .order.client.preferredDisplayName }!
+ execute:
+ sequentially:
+ - getAvailablePets:
+ call: getAvailablePets
+ output:
+ from: "$input + { availablePets: [.[] | select(.category.name == "dog" and (.tags[] | .breed == $input.order.breed))] }"
+ - submitMatchesByMail:
+ call: http
+ with:
+ method: post
+ endpoint:
+ uri: https://fake.smtp.service.com/email/send
+ authentication: petStoreOAuth2
+ body:
+ from: noreply@fake.petstore.com
+ to: ${ .order.client.email }
+ subject: Candidates for Adoption
+ body: >
+ Hello ${ .order.client.preferredDisplayName }!
- Following your interest to adopt a dog, here is a list of candidates that you might be interested in:
+ Following your interest to adopt a dog, here is a list of candidates that you might be interested in:
- ${ .pets | map("-\(.name)") | join("\n") }
+ ${ .pets | map("-\(.name)") | join("\n") }
- Please do not hesistate to contact us at info@fake.petstore.com if your have questions.
+ Please do not hesistate to contact us at info@fake.petstore.com if your have questions.
- Hope to hear from you soon!
+ Hope to hear from you soon!
- ----------------------------------------------------------------------------------------------
- DO NOT REPLY
- ----------------------------------------------------------------------------------------------
+ ----------------------------------------------------------------------------------------------
+ DO NOT REPLY
+ ----------------------------------------------------------------------------------------------
```
### Task
@@ -255,11 +257,10 @@ document:
name: sample-workflow
version: '0.1.0'
do:
- getPetById:
- call: http
- with:
- method: get
- endpoint: https://petstore.swagger.io/v2/pet/{petId}
+ call: http
+ with:
+ method: get
+ endpoint: https://petstore.swagger.io/v2/pet/{petId}
```
Serverless Workflow defines several default functions that **MUST** be supported by all implementations and runtimes:
@@ -294,16 +295,15 @@ document:
name: sample-workflow
version: '0.1.0'
do:
- greetUser:
- call: asyncapi
- with:
- document: https://fake.com/docs/asyncapi.json
- operation: findPetsByStatus
- server: staging
- message: getPetByStatusQuery
- binding: http
- payload:
- petId: ${ .pet.id }
+ call: asyncapi
+ with:
+ document: https://fake.com/docs/asyncapi.json
+ operation: findPetsByStatus
+ server: staging
+ message: getPetByStatusQuery
+ binding: http
+ payload:
+ petId: ${ .pet.id }
```
##### gRPC Call
@@ -331,17 +331,16 @@ document:
name: sample-workflow
version: '0.1.0'
do:
- greetUser:
- call: grpc
- with:
- proto: file://app/greet.proto
- service:
- name: GreeterApi.Greeter
- host: localhost
- port: 5011
- method: SayHello
- arguments:
- name: ${ .user.preferredDisplayName }
+ call: grpc
+ with:
+ proto: file://app/greet.proto
+ service:
+ name: GreeterApi.Greeter
+ host: localhost
+ port: 5011
+ method: SayHello
+ arguments:
+ name: ${ .user.preferredDisplayName }
```
##### HTTP Call
@@ -367,11 +366,10 @@ document:
name: sample-workflow
version: '0.1.0'
do:
- getPetById:
- call: http
- with:
- method: get
- endpoint: https://petstore.swagger.io/v2/pet/{petId}
+ call: http
+ with:
+ method: get
+ endpoint: https://petstore.swagger.io/v2/pet/{petId}
```
##### OpenAPI Call
@@ -397,13 +395,12 @@ document:
name: sample-workflow
version: '0.1.0'
do:
- getPets:
- call: openapi
- with:
- document: https://petstore.swagger.io/v2/swagger.json
- operation: findPetsByStatus
- parameters:
- status: available
+ call: openapi
+ with:
+ document: https://petstore.swagger.io/v2/swagger.json
+ operation: findPetsByStatus
+ parameters:
+ status: available
```
#### Composite
@@ -414,8 +411,8 @@ do:
| Name | Type | Required | Description|
|:--|:---:|:---:|:---|
-| execute.sequentially | [`map(string, task)`](#task) | `no` | The tasks to perform sequentially.
*Required if `execute.concurrently` has not been set, otherwise ignored.*
*If set, must contains **at least** two [`tasks`](#task).* |
-| execute.concurrently | [`map(string, task)`](#task) | `no` | The tasks to perform concurrently.
*Required if `execute.sequentially` has not been set, otherwise ignored.*
*If set, must contains **at least** two [`tasks`](#task).* |
+| execute.sequentially | [`map[string, task][]`](#task) | `no` | The tasks to perform sequentially.
*Required if `execute.concurrently` has not been set, otherwise ignored.*
*If set, must contains **at least** two [`tasks`](#task).* |
+| execute.concurrently | [`map[string, task][]`](#task) | `no` | The tasks to perform concurrently.
*Required if `execute.sequentially` has not been set, otherwise ignored.*
*If set, must contains **at least** two [`tasks`](#task).* |
| execute.compete | `boolean` | `no` | Indicates whether or not the concurrent [`tasks`](#task) are racing against each other, with a single possible winner, which sets the composite task's output.
*Ignored if `execute.sequentially` has been set. Defaults to `false`.*
*Must **not** be set if the [`tasks`](#task) are executed sequentially.* |
##### Examples
@@ -428,10 +425,9 @@ document:
name: sample-workflow
version: '0.1.0'
do:
- bookTrip:
- execute:
- sequentially:
- bookHotel:
+ execute:
+ sequentially:
+ - bookHotel:
call: http
with:
method: post
@@ -442,7 +438,7 @@ do:
name: Four Seasons
city: Antwerp
country: Belgium
- bookFlight:
+ - bookFlight:
call: http
with:
method: post
@@ -474,10 +470,9 @@ document:
name: sample-workflow
version: '0.1.0'
do:
- raiseAlarm:
- execute:
- concurrently:
- callNurse:
+ execute:
+ concurrently:
+ - callNurse:
call: http
with:
method: put
@@ -485,7 +480,7 @@ do:
body:
patientId: ${ .patient.fullName }
room: ${ .room.number }
- callDoctor:
+ - callDoctor:
call: http
with:
method: put
@@ -514,19 +509,18 @@ document:
name: sample-workflow
version: '0.1.0'
do:
- placeOrder:
- emit:
- event:
- with:
- source: https://petstore.com
- type: com.petstore.order.placed.v1
- data:
- client:
- firstName: Cruella
- lastName: de Vil
- items:
- - breed: dalmatian
- quantity: 101
+ emit:
+ event:
+ with:
+ source: https://petstore.com
+ type: com.petstore.order.placed.v1
+ data:
+ client:
+ firstName: Cruella
+ lastName: de Vil
+ items:
+ - breed: dalmatian
+ quantity: 101
```
#### For
@@ -552,22 +546,19 @@ document:
name: sample-workflow
version: '0.1.0'
do:
- checkup:
- for:
- each: pet
- in: .pets
- at: index
- while: .vet != null
- do:
- checkForFleas:
- if: $pet.lastCheckup == null
- listen:
- to:
- one:
- with:
- type: com.fake.petclinic.pets.checkup.completed.v2
- output:
- to: '.pets + [{ "id": $pet.id }]'
+ for:
+ each: pet
+ in: .pets
+ at: index
+ while: .vet != null
+ do:
+ listen:
+ to:
+ one:
+ with:
+ type: com.fake.petclinic.pets.checkup.completed.v2
+ output:
+ to: '.pets + [{ "id": $pet.id }]'
```
#### Listen
@@ -589,18 +580,17 @@ document:
name: sample-workflow
version: '0.1.0'
do:
- callDoctor:
- listen:
- to:
- any:
- - with:
- type: com.fake-hospital.vitals.measurements.temperature
- data:
- temperature: ${ .temperature > 38 }
- - with:
- type: com.fake-hospital.vitals.measurements.bpm
- data:
- temperature: ${ .bpm < 60 or .bpm > 100 }
+ listen:
+ to:
+ any:
+ - with:
+ type: com.fake-hospital.vitals.measurements.temperature
+ data:
+ temperature: ${ .temperature > 38 }
+ - with:
+ type: com.fake-hospital.vitals.measurements.bpm
+ data:
+ temperature: ${ .bpm < 60 or .bpm > 100 }
```
#### Raise
@@ -622,28 +612,30 @@ document:
name: sample-workflow
version: '0.1.0'
do:
- processTicket:
- switch:
- highPriority:
- when: .ticket.priority == "high"
- then: escalateToManager
- mediumPriority:
- when: .ticket.priority == "medium"
- then: assignToSpecialist
- lowPriority:
- when: .ticket.priority == "low"
- then: resolveTicket
- default:
- then: raiseUndefinedPriorityError
- raiseUndefinedPriorityError:
- raise:
- error:
- type: https://fake.com/errors/tickets/undefined-priority
- status: 400
- title: Undefined Priority
- escalateToManager: {...}
- assignToSpecialist: {...}
- resolveTicket: {...}
+ execute:
+ sequentially:
+ - processTicket:
+ switch:
+ - highPriority:
+ when: .ticket.priority == "high"
+ then: escalateToManager
+ - mediumPriority:
+ when: .ticket.priority == "medium"
+ then: assignToSpecialist
+ - lowPriority:
+ when: .ticket.priority == "low"
+ then: resolveTicket
+ - default:
+ then: raiseUndefinedPriorityError
+ - raiseUndefinedPriorityError:
+ raise:
+ error:
+ type: https://fake.com/errors/tickets/undefined-priority
+ status: 400
+ title: Undefined Priority
+ - escalateToManager: {}
+ - assignToSpecialist: {}
+ - resolveTicket: {}
```
#### Run
@@ -668,29 +660,30 @@ document:
name: sample-workflow
version: '0.1.0'
do:
-
- runContainer:
- run:
- container:
- image: fake-image
-
- runScript:
- run:
- script:
- language: js
- code: >
- Some cool multiline script
-
- runShell:
- run:
- shell:
- command: 'echo "Hello, ${ .user.name }"'
-
- runWorkflow:
- run:
- workflow:
- reference: another-one:0.1.0
- input: {}
+ execute:
+ sequentially:
+ - runContainer:
+ run:
+ container:
+ image: fake-image
+
+ - runScript:
+ run:
+ script:
+ language: js
+ code: >
+ Some cool multiline script
+
+ - runShell:
+ run:
+ shell:
+ command: 'echo "Hello, ${ .user.name }"'
+
+ - runWorkflow:
+ run:
+ workflow:
+ reference: another-one:0.1.0
+ input: {}
```
##### Container Process
@@ -716,10 +709,9 @@ document:
name: sample-workflow
version: '0.1.0'
do:
- runContainer:
- run:
- container:
- image: fake-image
+ run:
+ container:
+ image: fake-image
```
##### Script Process
@@ -744,12 +736,11 @@ document:
name: sample-workflow
version: '0.1.0'
do:
- runScript:
- run:
- script:
- language: js
- code: >
- Some cool multiline script
+ run:
+ script:
+ language: js
+ code: >
+ Some cool multiline script
```
##### Shell Process
@@ -773,10 +764,9 @@ document:
name: sample-workflow
version: '0.1.0'
do:
- runShell:
- run:
- shell:
- command: 'echo "Hello, ${ .user.name }"'
+ run:
+ shell:
+ command: 'echo "Hello, ${ .user.name }"'
```
##### Workflow Process
@@ -800,12 +790,11 @@ document:
name: sample-workflow
version: '0.1.0'
do:
- runShell:
- run:
- workflow:
- reference: another-one:0.1.0
- input:
- foo: bar
+ run:
+ workflow:
+ reference: another-one:0.1.0
+ input:
+ foo: bar
```
#### Set
@@ -827,11 +816,10 @@ document:
name: set
version: '0.1.0'
do:
- initialize:
- set:
- shape: circle
- size: ${ .configuration.size }
- fill: ${ .configuration.fill }
+ set:
+ shape: circle
+ size: ${ .configuration.size }
+ fill: ${ .configuration.fill }
```
#### Switch
@@ -842,7 +830,7 @@ Enables conditional branching within workflows, allowing them to dynamically sel
| Name | Type | Required | Description |
|:--|:---:|:---:|:---|
-| switch | [`map[string, case]`](#switch-case) | `yes` | A name/value map of the cases to switch on |
+| switch | [`case[]`](#switch-case) | `yes` | A name/value map of the cases to switch on |
##### Examples
@@ -853,34 +841,36 @@ document:
name: sample-workflow
version: '0.1.0'
do:
- processOrder:
- switch:
- case1:
- when: .orderType == "electronic"
- then: processElectronicOrder
- case2:
- when: .orderType == "physical"
- then: processPhysicalOrder
- default:
- then: handleUnknownOrderType
- processElectronicOrder:
- execute:
- sequentially:
- validatePayment: {...}
- fulfillOrder: {...}
- then: exit
- processPhysicalOrder:
- execute:
- sequentially:
- checkInventory: {...}
- packItems: {...}
- scheduleShipping: {...}
- then: exit
- handleUnknownOrderType:
- execute:
- sequentially:
- logWarning: {...}
- notifyAdmin: {...}
+ execute:
+ sequentially:
+ - processOrder:
+ switch:
+ - case1:
+ when: .orderType == "electronic"
+ then: processElectronicOrder
+ - case2:
+ when: .orderType == "physical"
+ then: processPhysicalOrder
+ - default:
+ then: handleUnknownOrderType
+ - processElectronicOrder:
+ execute:
+ sequentially:
+ - validatePayment: {}
+ - fulfillOrder: {}
+ then: exit
+ - processPhysicalOrder:
+ execute:
+ sequentially:
+ - checkInventory: {}
+ - packItems: {}
+ - scheduleShipping: {}
+ then: exit
+ - handleUnknownOrderType:
+ execute:
+ sequentially:
+ - logWarning: {}
+ - notifyAdmin: {}
```
##### Switch Case
@@ -900,7 +890,7 @@ Serves as a mechanism within workflows to handle errors gracefully, potentially
| Name | Type | Required | Description|
|:--|:---:|:---:|:---|
-| try | [`task`](#task) | `yes` | The task to perform. |
+| try | [`task`](#task) | `yes` | The task(s) to perform. |
| catch | [`catch`](#catch) | `yes` | Configures the errors to catch and how to handle them. |
##### Examples
@@ -912,26 +902,25 @@ document:
name: sample-workflow
version: '0.1.0'
do:
- processOrder:
- try:
- call: http
+ try:
+ call: http
+ with:
+ method: get
+ endpoint: https://
+ catch:
+ errors:
with:
- method: get
- endpoint: https://
- catch:
- errors:
- with:
- type: https://serverlessworkflow.io.io/dsl/errors/types/communication
- status: 503
- as: error
- retry:
- delay:
- seconds: 3
- backoff:
- exponential: {}
- limit:
- attempt:
- count: 5
+ type: https://serverlessworkflow.io.io/dsl/errors/types/communication
+ status: 503
+ as: error
+ retry:
+ delay:
+ seconds: 3
+ backoff:
+ exponential: {}
+ limit:
+ attempt:
+ count: 5
```
##### Catch
@@ -968,9 +957,8 @@ document:
name: sample-workflow
version: '0.1.0'
do:
- delay10Seconds:
- wait:
- seconds: 10
+ wait:
+ seconds: 10
```
### Flow Directive
@@ -979,9 +967,10 @@ Flow Directives are commands within a workflow that dictate its progression.
| Directive | Description |
| --------- | ----------- |
-| `continue` | Instructs the workflow to proceed with the next task in line. This action may conclude the execution of a particular workflow or branch if there are not task defined after the continue one. |
-| `exit` | Halts the current branch's execution, potentially terminating the entire workflow if the current task resides within the main branch. |
-| `end` | Provides a graceful conclusion to the workflow execution, signaling its completion explicitly. |
+| `"continue"` | Instructs the workflow to proceed with the next task in line. This action may conclude the execution of a particular workflow or branch if there are not task defined after the continue one. |
+| `"exit"` | Halts the current branch's execution, potentially terminating the entire workflow if the current task resides within the main branch. |
+| `"end"` | Provides a graceful conclusion to the workflow execution, signaling its completion explicitly. |
+| `string` | Continues the workflow at the task with the specified name |
### External Resource
@@ -1035,13 +1024,12 @@ use:
sampleBasicFromSecret:
basic: usernamePasswordSecret
do:
- getMessages:
- call: http
- with:
- method: get
- endpoint:
- uri: https://secured.fake.com/sample
- authentication: sampleBasicFromSecret
+ call: http
+ with:
+ method: get
+ endpoint:
+ uri: https://secured.fake.com/sample
+ authentication: sampleBasicFromSecret
```
#### Basic Authentication
@@ -1070,13 +1058,12 @@ use:
username: admin
password: 123
do:
- getMessages:
- call: http
- with:
- method: get
- endpoint:
- uri: https://secured.fake.com/sample
- authentication: sampleBasic
+ call: http
+ with:
+ method: get
+ endpoint:
+ uri: https://secured.fake.com/sample
+ authentication: sampleBasic
```
#### Bearer Authentication
@@ -1098,15 +1085,14 @@ document:
name: sample-workflow
version: '0.1.0'
do:
- getMessages:
- call: http
- with:
- method: get
- endpoint:
- uri: https://secured.fake.com/sample
- authentication:
- bearer:
- token: ${ .user.token }
+ call: http
+ with:
+ method: get
+ endpoint:
+ uri: https://secured.fake.com/sample
+ authentication:
+ bearer:
+ token: ${ .user.token }
```
#### Certificate Authentication
@@ -1143,21 +1129,20 @@ document:
name: sample-workflow
version: '0.1.0'
do:
- getMessages:
- call: http
- with:
- method: get
- endpoint:
- uri: https://secured.fake.com/sample
- authentication:
- oauth2:
- authority: http://keycloak/realms/fake-authority/.well-known/openid-configuration
- grant: client-credentials
- client:
- id: workflow-runtime
- secret: **********
- scopes: [ api ]
- audiences: [ runtime ]
+ call: http
+ with:
+ method: get
+ endpoint:
+ uri: https://secured.fake.com/sample
+ authentication:
+ oauth2:
+ authority: http://keycloak/realms/fake-authority/.well-known/openid-configuration
+ grant: client-credentials
+ client:
+ id: workflow-runtime
+ secret: **********
+ scopes: [ api ]
+ audiences: [ runtime ]
```
##### OAUTH2 Token
@@ -1197,28 +1182,27 @@ document:
version: '0.1.0'
use:
extensions:
- logging:
- extend: all
- before:
- call: http
- with:
- method: post
- endpoint: https://fake.log.collector.com
- body:
- message: "${ \"Executing task '\($task.reference)'...\" }"
- after:
- call: http
- with:
- method: post
- endpoint: https://fake.log.collector.com
- body:
- message: "${ \"Executed task '\($task.reference)'...\" }"
+ - logging:
+ extend: all
+ before:
+ call: http
+ with:
+ method: post
+ endpoint: https://fake.log.collector.com
+ body:
+ message: "${ \"Executing task '\($task.reference)'...\" }"
+ after:
+ call: http
+ with:
+ method: post
+ endpoint: https://fake.log.collector.com
+ body:
+ message: "${ \"Executed task '\($task.reference)'...\" }"
do:
- get:
- call: http
- with:
- method: get
- endpoint: https://fake.com/sample
+ call: http
+ with:
+ method: get
+ endpoint: https://fake.com/sample
```
*Intercept HTTP calls to 'https://mocked.service.com' and mock its response:*
@@ -1230,24 +1214,23 @@ document:
version: '0.1.0'
use:
extensions:
- mockService:
- extend: http
- when: ($task.with.uri != null and ($task.with.uri | startswith("https://mocked.service.com"))) or ($task.with.endpoint.uri != null and ($task.with.endpoint.uri | startswith("https://mocked.service.com")))
- before:
- set:
- statusCode: 200
- headers:
- Content-Type: application/json
- content:
- foo:
- bar: baz
- then: exit #using this, we indicate to the workflow we want to exit the extended task, thus just returning what we injected
+ - mockService:
+ extend: http
+ when: ($task.with.uri != null and ($task.with.uri | startswith("https://mocked.service.com"))) or ($task.with.endpoint.uri != null and ($task.with.endpoint.uri | startswith("https://mocked.service.com")))
+ before:
+ set:
+ statusCode: 200
+ headers:
+ Content-Type: application/json
+ content:
+ foo:
+ bar: baz
+ then: exit #using this, we indicate to the workflow we want to exit the extended task, thus just returning what we injected
do:
- get:
- call: http
- with:
- method: get
- endpoint: https://fake.com/sample
+ call: http
+ with:
+ method: get
+ endpoint: https://fake.com/sample
```
### Error
@@ -1488,9 +1471,8 @@ document:
name: sample
version: '0.1.0'
do:
- waitFor60Seconds:
- wait:
- seconds: 60
+ wait:
+ seconds: 60
timeout:
after:
seconds: 30
diff --git a/dsl.md b/dsl.md
index 900c5fb0..b481d9c5 100644
--- a/dsl.md
+++ b/dsl.md
@@ -342,10 +342,9 @@ document:
version: '0.1.0'
do:
- validateEmail:
- call: https://github.com/myorg/functions/validateEmailAddress@v1
- with:
- emailAddress: ${ .userEmail }
+ call: https://github.com/myorg/functions/validateEmailAddress@v1
+ with:
+ emailAddress: ${ .userEmail }
```
##### Publishing a Custom Function
@@ -426,11 +425,10 @@ use:
body:
message: "${ \"Executed task '\($task.reference)'...\" }"
do:
- get:
- call: http
- with:
- method: get
- uri: https://fake.com/sample
+ call: http
+ with:
+ method: get
+ uri: https://fake.com/sample
```
### External Resources
diff --git a/examples/accumulate-room-readings.yaml b/examples/accumulate-room-readings.yaml
index d7d91eec..5b322b07 100644
--- a/examples/accumulate-room-readings.yaml
+++ b/examples/accumulate-room-readings.yaml
@@ -4,43 +4,45 @@ document:
name: accumulate-room-readings
version: 1.0.0-alpha1
do:
- consumeReading:
- listen:
- to:
- all:
- - with:
- source: https://my.home.com/sensor
- type: my.home.sensors.temperature
- correlate:
- roomId:
- from: .roomid
- output:
- from: .data.reading
- - with:
- source: https://my.home.com/sensor
- type: my.home.sensors.humidity
- correlate:
- roomId:
- from: .roomid
- output:
- from: .data.reading
- as: readings
- logReading:
- for:
- each: reading
- in: .readings
- do:
- call: openapi
- with:
- document:
- uri: http://myorg.io/ordersservices.json
- operationId: logreading
- generateReport:
- call: openapi
- with:
- document:
- uri: http://myorg.io/ordersservices.json
- operationId: produceReport
+ execute:
+ sequentially:
+ - consumeReading:
+ listen:
+ to:
+ all:
+ - with:
+ source: https://my.home.com/sensor
+ type: my.home.sensors.temperature
+ correlate:
+ roomId:
+ from: .roomid
+ output:
+ from: .data.reading
+ - with:
+ source: https://my.home.com/sensor
+ type: my.home.sensors.humidity
+ correlate:
+ roomId:
+ from: .roomid
+ output:
+ from: .data.reading
+ as: readings
+ - logReading:
+ for:
+ each: reading
+ in: .readings
+ do:
+ call: openapi
+ with:
+ document:
+ uri: http://myorg.io/ordersservices.json
+ operationId: logreading
+ - generateReport:
+ call: openapi
+ with:
+ document:
+ uri: http://myorg.io/ordersservices.json
+ operationId: produceReport
timeout:
after:
hours: 1
\ No newline at end of file
diff --git a/examples/asyncapi.yaml b/examples/asyncapi.yaml
index 9d442d08..ca6ff26d 100644
--- a/examples/asyncapi.yaml
+++ b/examples/asyncapi.yaml
@@ -4,17 +4,16 @@ document:
name: bearer-auth
version: 1.0.0-alpha1
do:
- greetUser:
- call: asyncapi
- with:
- document:
- uri: https://fake.com/docs/asyncapi.json
- operationRef: findPetsByStatus
- server: staging
- message: getPetByStatusQuery
- binding: http
- payload:
- petId: ${ .pet.id }
- authentication:
- bearer:
- token: ${ .token }
+ call: asyncapi
+ with:
+ document:
+ uri: https://fake.com/docs/asyncapi.json
+ operationRef: findPetsByStatus
+ server: staging
+ message: getPetByStatusQuery
+ binding: http
+ payload:
+ petId: ${ .pet.id }
+ authentication:
+ bearer:
+ token: ${ .token }
diff --git a/examples/bearer-auth-uri-format.yaml b/examples/bearer-auth-uri-format.yaml
index 622aae2d..2a0700ec 100644
--- a/examples/bearer-auth-uri-format.yaml
+++ b/examples/bearer-auth-uri-format.yaml
@@ -4,12 +4,11 @@ document:
name: bearer-auth-uri-format
version: 1.0.0-alpha1
do:
- getPetById:
- call: http
- with:
- method: get
- endpoint:
- uri: https://petstore.swagger.io/v2/pet/1
- authentication:
- bearer:
- token: ${ .token }
+ call: http
+ with:
+ method: get
+ endpoint:
+ uri: https://petstore.swagger.io/v2/pet/1
+ authentication:
+ bearer:
+ token: ${ .token }
diff --git a/examples/bearer-auth.yaml b/examples/bearer-auth.yaml
index f4b2227c..46e72bf1 100644
--- a/examples/bearer-auth.yaml
+++ b/examples/bearer-auth.yaml
@@ -4,12 +4,11 @@ document:
name: bearer-auth
version: 1.0.0-alpha1
do:
- getPetById:
- call: http
- with:
- method: get
- endpoint:
- uri: https://petstore.swagger.io/v2/pet/{petId}
- authentication:
- bearer:
- token: ${ .token }
+ call: http
+ with:
+ method: get
+ endpoint:
+ uri: https://petstore.swagger.io/v2/pet/{petId}
+ authentication:
+ bearer:
+ token: ${ .token }
diff --git a/examples/call-http-shorthand-endpoint.yaml b/examples/call-http-shorthand-endpoint.yaml
index f682ed30..52b606b2 100644
--- a/examples/call-http-shorthand-endpoint.yaml
+++ b/examples/call-http-shorthand-endpoint.yaml
@@ -4,8 +4,7 @@ document:
name: call-http-shorthand-endpoint
version: 1.0.0-alpha1
do:
- getPetById:
- call: http
- with:
- method: get
- endpoint: https://petstore.swagger.io/v2/pet/{petId}
+ call: http
+ with:
+ method: get
+ endpoint: https://petstore.swagger.io/v2/pet/{petId}
diff --git a/examples/do-single.yaml b/examples/do-single.yaml
new file mode 100644
index 00000000..52b606b2
--- /dev/null
+++ b/examples/do-single.yaml
@@ -0,0 +1,10 @@
+document:
+ dsl: 1.0.0-alpha1
+ namespace: examples
+ name: call-http-shorthand-endpoint
+ version: 1.0.0-alpha1
+do:
+ call: http
+ with:
+ method: get
+ endpoint: https://petstore.swagger.io/v2/pet/{petId}
diff --git a/examples/mock-service-extension.yaml b/examples/mock-service-extension.yaml
new file mode 100644
index 00000000..4a6c7724
--- /dev/null
+++ b/examples/mock-service-extension.yaml
@@ -0,0 +1,25 @@
+document:
+ dsl: '1.0.0-alpha1'
+ namespace: test
+ name: sample-workflow
+ version: '0.1.0'
+use:
+ extensions:
+ - mockService:
+ extend: call
+ when: ($task.with.endpoint != null and ($task.with.endpoint | startswith("https://mocked.service.com"))) or ($task.with.endpoint.uri != null and ($task.with.endpoint.uri | startswith("https://mocked.service.com")))
+ before:
+ set:
+ statusCode: 200
+ headers:
+ Content-Type: application/json
+ content:
+ foo:
+ bar: baz
+ then: exit #using this, we indicate to the workflow we want to exit the extended task, thus just returning what we injected
+do:
+ call: http
+ with:
+ method: get
+ endpoint:
+ uri: https://fake.com/sample
\ No newline at end of file
diff --git a/examples/switch-then-string.yaml b/examples/switch-then-string.yaml
index 7db53745..99c69ea1 100644
--- a/examples/switch-then-string.yaml
+++ b/examples/switch-then-string.yaml
@@ -4,45 +4,47 @@ document:
name: sample-workflow
version: '0.1.0'
do:
- processOrder:
- switch:
- case1:
- when: .orderType == "electronic"
- then: processElectronicOrder
- case2:
- when: .orderType == "physical"
- then: processPhysicalOrder
- default:
- then: handleUnknownOrderType
- processElectronicOrder:
- execute:
- sequentially:
- validatePayment:
- set:
- validate: true
- fulfillOrder:
- set:
- status: fulfilled
- then: exit
- processPhysicalOrder:
- execute:
- sequentially:
- checkInventory:
- set:
- inventory: clear
- packItems:
- set:
- items: 1
- scheduleShipping:
- set:
- address: Elmer St
- then: exit
- handleUnknownOrderType:
- execute:
- sequentially:
- logWarning:
- set:
- log: warn
- notifyAdmin:
- set:
- message: something's wrong
\ No newline at end of file
+ execute:
+ sequentially:
+ - processOrder:
+ switch:
+ - case1:
+ when: .orderType == "electronic"
+ then: processElectronicOrder
+ - case2:
+ when: .orderType == "physical"
+ then: processPhysicalOrder
+ - default:
+ then: handleUnknownOrderType
+ - processElectronicOrder:
+ execute:
+ sequentially:
+ - validatePayment:
+ set:
+ validate: true
+ - fulfillOrder:
+ set:
+ status: fulfilled
+ then: exit
+ - processPhysicalOrder:
+ execute:
+ sequentially:
+ - checkInventory:
+ set:
+ inventory: clear
+ - packItems:
+ set:
+ items: 1
+ - scheduleShipping:
+ set:
+ address: Elmer St
+ then: exit
+ - handleUnknownOrderType:
+ execute:
+ sequentially:
+ - logWarning:
+ set:
+ log: warn
+ - notifyAdmin:
+ set:
+ message: something's wrong
\ No newline at end of file
diff --git a/examples/use-authentication.yaml b/examples/use-authentication.yaml
index c8cd34fe..613764df 100644
--- a/examples/use-authentication.yaml
+++ b/examples/use-authentication.yaml
@@ -9,10 +9,9 @@ use:
bearer:
token: ${ .token }
do:
- getPetById:
- call: http
- with:
- method: get
- endpoint:
- uri: https://petstore.swagger.io/v2/pet/{petId}
- authentication: petStoreAuth
+ call: http
+ with:
+ method: get
+ endpoint:
+ uri: https://petstore.swagger.io/v2/pet/{petId}
+ authentication: petStoreAuth
diff --git a/schema/workflow.yaml b/schema/workflow.yaml
index 75c2093e..d83a7b45 100644
--- a/schema/workflow.yaml
+++ b/schema/workflow.yaml
@@ -51,9 +51,13 @@ properties:
$ref: '#/$defs/error'
description: The workflow's reusable errors.
extensions:
- type: object
- additionalProperties:
- $ref: '#/$defs/extension'
+ type: array
+ items:
+ type: object
+ minProperties: 1
+ maxProperties: 1
+ additionalProperties:
+ $ref: '#/$defs/extension'
description: The workflow's extensions.
functions:
type: object
@@ -72,11 +76,8 @@ properties:
description: The workflow's secrets.
description: Defines the workflow's reusable components.
do:
- type: object
- minProperties: 1
- additionalProperties:
- $ref: '#/$defs/task'
- description: Defines the tasks the workflow must perform
+ description: Defines the task the workflow must perform
+ $ref: '#/$defs/task'
timeout:
$ref: '#/$defs/timeout'
description: The workflow's timeout configuration, if any.
@@ -273,33 +274,42 @@ $defs:
description: A name/value mapping of the parameters, if any, to call the function with.
required: [ call ]
compositeTask:
- type: object
+ type: object
+ required: [ execute ]
+ description: Serves as a pivotal orchestrator within workflow systems, enabling the seamless integration and execution of multiple subtasks to accomplish complex operations
properties:
execute:
type: object
- oneOf:
- - properties:
- concurrently:
- type: object
- minProperties: 2
- additionalProperties:
- $ref: '#/$defs/task'
- description: A name/definition mapping of the tasks to perform concurrently.
- compete:
- type: boolean
- description: Indicates whether or not the concurrent tasks are racing against each other, with a single possible winner, which sets the composite task's output.
- required: [ concurrently ]
- - properties:
- sequentially:
- type: object
- minProperties: 2
- additionalProperties:
- $ref: '#/$defs/task'
- description: A name/definition mapping of the tasks to perform sequentially.
- required: [ sequentially ]
description: Configures the task execution strategy to use
- required: [ execute ]
- description: Serves as a pivotal orchestrator within workflow systems, enabling the seamless integration and execution of multiple subtasks to accomplish complex operations
+ oneOf:
+ - required: [ concurrently ]
+ properties:
+ concurrently:
+ description: A list of the tasks to perform concurrently.
+ type: array
+ minItems: 2
+ items:
+ type: object
+ minProperties: 1
+ maxProperties: 1
+ additionalProperties:
+ $ref: '#/$defs/task'
+ compete:
+ description: Indicates whether or not the concurrent tasks are racing against each other, with a single possible winner, which sets the composite task's output.
+ type: boolean
+ default: false
+ - required: [ sequentially ]
+ properties:
+ sequentially:
+ description: A list of the tasks to perform sequentially.
+ type: array
+ minItems: 2
+ items:
+ type: object
+ minProperties: 1
+ maxProperties: 1
+ additionalProperties:
+ $ref: '#/$defs/task'
emitTask:
type: object
properties:
@@ -499,25 +509,32 @@ $defs:
type: object
properties:
switch:
- type: object
- minProperties: 1
- additionalProperties:
+ type: array
+ minItems: 1
+ items:
type: object
- properties:
- when:
- type: string
- description: A runtime expression used to determine whether or not the case matches.
- then:
- $ref: '#/$defs/flowDirective'
- description: The flow directive to execute when the case matches.
+ minProperties: 1
+ maxProperties: 1
+ additionalProperties:
+ type: object
+ properties:
+ name:
+ type: string
+ description: The case's name.
+ when:
+ type: string
+ description: A runtime expression used to determine whether or not the case matches.
+ then:
+ $ref: '#/$defs/flowDirective'
+ description: The flow directive to execute when the case matches.
required: [ switch ]
description: Enables conditional branching within workflows, allowing them to dynamically select different paths based on specified conditions or criteria
tryTask:
type: object
properties:
try:
- $ref: '#/$defs/task'
description: The task to perform.
+ $ref: '#/$defs/task'
catch:
type: object
properties:
@@ -536,8 +553,8 @@ $defs:
$ref: '#/$defs/retryPolicy'
description: The retry policy to use, if any, when catching errors.
do:
- $ref: '#/$defs/task'
description: The definition of the task to run when catching an error.
+ $ref: '#/$defs/task'
required: [ try, catch ]
description: Serves as a mechanism within workflows to handle errors gracefully, potentially retrying failed tasks before proceeding with alternate ones.
waitTask:
@@ -760,11 +777,11 @@ $defs:
type: string
description: A runtime expression, if any, used to determine whether or not the extension should apply in the specified context.
before:
- $ref: '#/$defs/task'
description: The task to execute before the extended task, if any.
- after:
$ref: '#/$defs/task'
+ after:
description: The task to execute after the extended task, if any.
+ $ref: '#/$defs/task'
required: [ extend ]
description: The definition of a an extension.
externalResource: