Skip to content

Commit cc7e8ff

Browse files
committed
docs: clarify async workflow step dependencies and success criteria
1 parent 5414803 commit cc7e8ff

1 file changed

Lines changed: 37 additions & 1 deletion

File tree

src/arazzo.md

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -432,13 +432,49 @@ Describes a single workflow step which MAY be a call to an API operation ([OpenA
432432
| <a name="stepOnSuccess"></a>onSuccess | [[Success Action Object](#success-action-object) \| [Reusable Object](#reusable-object)] | An array of success action objects that specify what to do upon step success. If omitted, the next sequential step shall be executed as the default behavior. If multiple success actions have similar `criteria`, the first sequential action matching the criteria SHALL be the action executed. If a success action is already defined at the [Workflow](#workflow-object), the new definition will override it but can never remove it. If a Reusable Object is provided, it MUST link to a success action defined in the [components](#components-object) of the current Arazzo document. The list MUST NOT include duplicate success actions. |
433433
| <a name="stepOnFailure"></a>onFailure | [[Failure Action Object](#failure-action-object) \| [Reusable Object](#reusable-object)] | An array of failure action objects that specify what to do upon step failure. If omitted, the default behavior is to break and return. If multiple failure actions have similar `criteria`, the first sequential action matching the criteria SHALL be the action executed. If a failure action is already defined at the [Workflow](#workflow-object), the new definition will override it but can never remove it. If a Reusable Object is provided, it MUST link to a failure action defined in the [components](#components-object) of the current Arazzo document. The list MUST NOT include duplicate failure actions. |
434434
| <a name="stepOutputs"></a>outputs | Map[`string`, {expression} \| [Selector Object](#selector-object)] | A map between a friendly name and a dynamic output value defined using a [Runtime Expression](#runtime-expressions) or [Selector Object](#selector-object). The name MUST use keys that match the regular expression: `^[a-zA-Z0-9\.\-_]+$`. |
435-
| <a name="stepTimeout"></a>timeout | `integer` | The maximum number of milli-seconds to wait for the step to complete before aborting and failing the step. Consequently this will fail the workflow unless failureActions are defined. |
435+
| <a name="stepTimeout"></a>timeout | `integer` | The maximum number of milli-seconds to wait for the step to complete before aborting and failing the step. Consequently this will fail the workflow unless `onFailure` actions are defined. |
436436
| <a name="stepCorrelationId"></a>correlationId | `string` | A correlationId in AsyncAPI links a request with its response (or more broadly, to trace a single logical transaction across multiple asynchronous messages). Only applicable to `asyncapi` steps with action `receive` and has to be in-sync with correlationId defined in the AsyncAPI document. |
437437
| <a name="stepAction"></a>action | `send or receive` | Describes the intent of the message flow. Indicates whether the step will send (publish) or receive (subscribe) to a message on a channel described in an AsyncAPI document, Only applicable for `asyncapi` steps. |
438438
| <a name="stepDependsOn"></a>dependsOn | List[`string`] | A list of steps that MUST be completed before this step can be executed. `dependsOn` only establishes a prerequisite relationship for the current step and does not trigger execution of the referenced steps. Each value provided MUST be a `stepId`. The `stepId` value is case-sensitive. If the step depended on is defined within the **current workflow**, specify the `stepId` directly (e.g., `authStep`). If the step is defined in a **different workflow within the current Arazzo Document**, reference it using `$workflows.<workflowId>.steps.<stepId>`. If the step is defined in a **separate Arazzo Document**, the workflow MUST be defined in `sourceDescriptions` and referenced using `$sourceDescriptions.<name>.<workflowId>.steps.<stepId>` to avoid ambiguity. If your step depends on the output of a non-blocking/asynchronous step, then you SHOULD use `dependsOn` and refer to the async step using one of these patterns. |
439439

440440
This object MAY be extended with [Specification Extensions](#specification-extensions).
441441

442+
##### Step Dependencies and Execution Order
443+
444+
The `dependsOn` field at the step level is primarily intended to coordinate asynchronous operations.
445+
446+
**Recommended Approach for Synchronous Workflows**
447+
448+
For workflows containing only synchronous steps, the RECOMMENDED approach is to order steps sequentially in the steps array without using `dependsOn`. This provides the simplest and clearest execution model. Step-level `dependsOn` is typically unnecessary when all operations complete synchronously and execution follows a linear path.
449+
450+
**Use Case: Async Coordination**
451+
452+
When a step must wait for an asynchronous operation to complete before proceeding, `dependsOn` establishes a join point for in-flight async work. For example, a step that requests an order status SHOULD declare `dependsOn` on the step that receives order creation status from an async order placement, even if no explicit output reference exists. This ensures the async operation completes before the dependent step executes.
453+
454+
**Authoring Guidance**
455+
456+
For async workflows, authors SHOULD use `dependsOn` to explicitly declare when a step must wait for async work to complete, regardless of output references. This is the intended use case for step-level dependencies.
457+
458+
**Tool Behavior**
459+
460+
Tools MUST respect all declared `dependsOn` relationships. Tools MUST also treat runtime expression output references (e.g., `$steps.stepId.outputs.field`) as implicit dependencies and ensure the referenced step completes before the referencing step executes.
461+
462+
Tools supporting only sequential execution MUST execute steps in an order that satisfies both explicit (`dependsOn`) and implicit (output reference) dependencies.
463+
464+
**Validation Recommendations**
465+
466+
Implementations SHOULD validate the following scenario:
467+
468+
When no `dependsOn` is used in a workflow (sequential execution model), implementations SHOULD produce an error if a step references another step's outputs where the referenced step appears later in the steps array. This indicates a forward reference that cannot be satisfied in sequential execution.
469+
470+
##### Defining Success for Asynchronous Steps
471+
472+
For steps that reference AsyncAPI operations (via `operationId` or `channelPath`), tools will send or receive messages on the specified channel as defined by the referenced AsyncAPI description. For AsyncAPI send operations, the step completes immediately after the message is sent. Arazzo does not model broker acknowledgment or delivery confirmation. For AsyncAPI receive operations, step completion depends on message receipt as described below.
473+
474+
Because AsyncAPI channels MAY define multiple message types, and because message payloads MAY represent either success or failure conditions, authors MUST use `successCriteria` to explicitly define what constitutes step completion for AsyncAPI receive steps. The `successCriteria` SHOULD evaluate the received message payload (for example, via `$message.payload`) to determine whether the step succeeded.
475+
476+
If `correlationId` is specified, only messages matching the correlation identifier are considered. If no matching message is received within the `timeout` period, the step fails and triggers any defined `onFailure` actions.
477+
442478
##### Step Object Examples
443479

444480
A single step example:

0 commit comments

Comments
 (0)