Skip to main content
A workflow is the fundamental building block in Devset. It describes everything the engine needs to produce and dispatch events: which broker to target, how to connect to it, what the payload looks like, and the exact sequence of steps to execute. You define workflows as JSON documents, and Devset compiles them into an asynchronous execution plan that runs your pipeline as many times as you specify.

Complete Example

The following workflow produces ten order.created events to a Kafka topic, with a randomised order ID and a line-item count driven by workflow state:
{
  "id": "order-created-load",
  "messageType": "kafka",
  "contentType": "application/json",
  "producerName": "local-kafka",
  "topic": "orders",
  "schemaId": "order-schema",
  "executions": 10,
  "state": {
    "sequence": {
      "index": 0
    }
  },
  "pipeline": [
    {
      "stage": "build-order",
      "event": "order.created",
      "source": "none",
      "set": {
        "orderId": { "$fn": "uuid()" },
        "createdAt": { "$fn": "now()" },
        "itemCount": { "$fn": "int(1, 20)" },
        "status": { "$fn": "choice(pending, confirmed, processing)" }
      },
      "state": {
        "sequence.index": { "$fn": "add(state.sequence.index, 1)" }
      },
      "emit": true
    }
  ]
}

Field Reference

id
string
required
A unique identifier for this workflow. Used to reference the workflow in the UI and API. Choose a short, descriptive slug such as "order-created-load".
messageType
"kafka" | "rabbit"
default:"\"kafka\""
The target broker type. Set to "kafka" for Apache Kafka or "rabbit" for RabbitMQ. This determines which broker-specific fields are required (topic for Kafka; exchange and routingKey for RabbitMQ). Defaults to "kafka" when omitted.
contentType
"application/json" | "application/x-protobuf"
default:"\"application/json\""
The serialisation format for the event payload. Use "application/json" for human-readable JSON payloads or "application/x-protobuf" for binary Protobuf payloads. Defaults to "application/json" when omitted. When using Protobuf, you must also configure wireFormat on the relevant stage.
producerName
string
required
The name of the connector this workflow uses to reach the broker. The value must exactly match the name field of a configured Kafka or RabbitMQ connector. See Connectors for details.
topic
string
(Kafka only) The Kafka topic to which all events in this workflow are published. Required when messageType is "kafka".
exchange
string
(RabbitMQ only) The RabbitMQ exchange to which events are published. Required when messageType is "rabbit".
routingKey
string
(RabbitMQ only) The routing key attached to every published message. Required when messageType is "rabbit".
schemaId
string
The default schema applied to all stages in this workflow. Individual stages can override this with their own schemaId. Schemas are managed in the Schema Repo and drive field validation and the Function Studio field picker.
executions
integer
default:"1"
The number of times the full pipeline runs. Setting executions: 10 causes the engine to run the entire pipeline — every stage in order — ten times. Each execution is independent and receives the same initial state seed. Defaults to 1 when omitted.
state
object
The initial mutable state for the workflow. State is seeded once per execution and is readable and writable by every stage in the pipeline. Use dot-notation keys inside stage state blocks to update nested paths. For example:
{
  "state": {
    "entity": { "count": 0 },
    "session": { "active": true }
  }
}
pipeline
Stage[]
required
An ordered array of stage objects. The engine executes stages sequentially within each execution. See Pipeline Stages for the full stage field reference.

Execution Model

When you run a workflow, Devset compiles the JSON document into an internal execution plan and schedules it asynchronously. Here is what happens for each execution:
  1. State is seeded. The state object from the workflow definition is copied into the execution context. Every execution starts with the same initial state, so executions are isolated from one another.
  2. The pipeline runs sequentially. Each stage is executed in array order. A stage can read the payload produced by the previous stage, mutate state, and conditionally emit an event to the broker.
  3. Events are dispatched. Stages with emit: true (or a truthy conditional emit) publish their payload to the configured broker using the named connector.
  4. The execution completes. After the last stage finishes, the execution is recorded in the run log. The engine starts the next execution until the executions count is exhausted.
Use state to carry counters, sequence numbers, or flags between stages within a single execution. Because each execution reseeds state from the workflow definition, state does not accumulate across executions.
The engine runs executions asynchronously and may parallelise them. If ordering across executions matters for your test scenario, design your pipeline so that ordering is enforced by the broker consumer under test rather than by Devset itself.

Broker-Specific Layouts

Kafka workflow — requires topic:
{
  "id": "payment-events",
  "messageType": "kafka",
  "contentType": "application/json",
  "producerName": "local-kafka",
  "topic": "payments",
  "executions": 5,
  "state": {},
  "pipeline": []
}
RabbitMQ workflow — requires exchange and routingKey:
{
  "id": "notification-events",
  "messageType": "rabbit",
  "contentType": "application/json",
  "producerName": "local-rabbit",
  "exchange": "notifications",
  "routingKey": "user.notify",
  "executions": 5,
  "state": {},
  "pipeline": []
}

Next Steps

  • Pipeline Stages — learn how to build each step in your pipeline
  • Expressions — use dynamic values, functions, and state references in your stages