Skip to content

Bindings

Dart workflows pass typed values through codecs. JSON workflows select data with bindings. The two solve different problems and must not be mixed.

Codecs

PayloadCodec<T> converts a typed Dart value to and from durable JSON. Use Codec.identity<T>() only for values already supported by JSON. The runtime never stores a Dart object.

Binding Context

JSON bindings evaluate against a stable context:

PathMeaning
$.inputWorkflow input
$.steps.<stepId>.outputPublished step output
$.resultCurrent task result while evaluating outputBinding
$.itemCurrent forEach item

Supported JSONPath: root, properties, quoted properties, array indexes, and wildcards. Filters, scripts, recursive descent, and functions are rejected. A missing path fails the decision instead of producing null.

JSON valueMeaning
"$.input.orderId"Read a value
"$$amount"The literal string $amount
"approved", 42, true, nullA literal
object or arrayRecursively evaluate nested values

Downstream Visibility

Downstream steps observe the published outputBinding, not hidden handler fields. Bindings are deterministic over workflow input and recorded step results.

Dart Data Flow

In Dart, return values from durable awaits. Do not write through a shared mutable map. Branch scopes receive their own WorkflowContext; results join as a typed map of branch names to values.

dart
final checks = await workflow.parallel(
  id: 'checks',
  branches: {
    'risk': (branch) => branch.serviceTask(riskCheck, order, id: 'risk'),
    'credit': (branch) => branch.serviceTask(creditCheck, order, id: 'credit'),
  },
);

See Also