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
π¨ Data Passing Example
This example shows how data is explicitly passed from one action to the next.
create-user
β
send-welcome-email
β
Complete
1. Input Models
public sealed class CreateUserInput
{
public string Name { get; init; } = string.Empty;
public string Email { get; init; } = string.Empty;
}
public sealed class WelcomeEmailInput
{
public string Name { get; init; } = string.Empty;
public string Email { get; init; } = string.Empty;
public string UserId { get; init; } = string.Empty;
}
2. Actions
[ActionName("create-user")]
public sealed class CreateUserAction : JobAction<CreateUserInput>
{
public override async Task<IActionResult> ExecuteAsync(
CreateUserInput input, CancellationToken ct)
{
// Simulate user creation
var userId = Guid.NewGuid().ToString("N")[..8];
Console.WriteLine($"Created user {input.Name} with ID {userId}");
// Pass the necessary data to the next step
return await NextAsync<SendWelcomeEmailAction>(
new WelcomeEmailInput
{
Name = input.Name,
Email = input.Email,
UserId = userId
});
}
}
[ActionName("send-welcome-email")]
public sealed class SendWelcomeEmailAction : JobAction<WelcomeEmailInput>
{
public override async Task<IActionResult> ExecuteAsync(
WelcomeEmailInput input, CancellationToken ct)
{
Console.WriteLine(
$"Sending welcome email to {input.Name} <{input.Email}> " +
$"(UserId: {input.UserId})");
return await CompleteAsync();
}
}
3. Registration
var wjb = WJbBuilder.Create(store, cfg =>
{
cfg.AddAction<CreateUserAction>();
cfg.AddAction<SendWelcomeEmailAction>();
});
4. Starting the Workflow
await wjb.EnqueueAsync("create-user",
new CreateUserInput
{
Name = "Alice",
Email = "alice@example.com"
});
5. Expected Output
Created user Alice with ID a1b2c3d4
Sending welcome email to Alice <alice@example.com> (UserId: a1b2c3d4)
Key Point
Data does not flow automatically.
The first action explicitly builds the payload for the next action. Only the information required by the next step is passed forward.