WJb Docs - Intermediate

Learn workflows, persistence, scheduling, and production-ready patterns.

πŸš€ Start Here
🧩 Mental Model
🌊 Building Workflows
πŸ’₯ Failures & Control
πŸ‘€ Observation & Debugging
πŸ›  Practical Patterns
βœ… Working Examples
➑️ What’s Next

πŸ“¨ Passing Data

Data moves between actions through the payload of the next job.

There is no hidden context or ambient state.


Basic Pattern

The current action creates a new payload and passes it to the next action:

public override async Task<IActionResult> ExecuteAsync(
    OrderInput input, CancellationToken ct)
{
    // process the order...

return await NextAsync<SendEmailAction>( new EmailInput { To = input.CustomerEmail, Subject = "Order Confirmation", Body = $"Your order {input.OrderId} has been received." }); }

The EmailInput object becomes the payload of the new job.


Strongly Typed Inputs

Each action declares the data it expects:

public sealed class EmailInput
{
    public string To { get; init; } = string.Empty;
    public string Subject { get; init; } = string.Empty;
    public string Body { get; init; } = string.Empty;
}

WJb automatically deserializes the job payload into this type.


Passing Results Forward

You can enrich or transform data before passing it on:

public override async Task<IActionResult> ExecuteAsync(
    ImportInput input, CancellationToken ct)
{
    var customers = await ImportCustomersAsync(input, ct);

return await NextAsync<ProcessCustomersAction>( new ProcessInput { Customers = customers, ImportedAt = DateTime.UtcNow }); }


Multiple Next with Different Data

Each command carries its own payload:

return Results.Next(
    JobCommands.Next<LogAction>(
        new LogInput { Message = "Import finished" }),
    JobCommands.Next<NotifyAction>(
        new NotifyInput
        {
            Email = input.AdminEmail,
            Count = customers.Count
        }));

What Is Not Shared Automatically

  • Local variables
  • Private fields of the action
  • Ambient context or HttpContext
  • Previous job results (unless you explicitly pass them)
Everything that the next action needs must be placed into its payload.

Best Practices

  • Keep payloads small and focused
  • Prefer strongly typed models over anonymous objects for public workflows
  • Pass only the data the next action actually needs
  • Avoid putting large files or binary data directly into payloads (use storage references instead)

Key Point

Data flow is explicit.

The current action decides exactly what information the next action will receive.

An unhandled error has occurred. Reload πŸ—™

Rejoining the server...

Rejoin failed... trying again in seconds.

Failed to rejoin.
Please retry or reload the page.

The session has been paused by the server.

Failed to resume the session.
Please retry or reload the page.