Actions (Tasks)
An Action (also called Task) is an individual processing unit within a rule that executes a function. Actions are the THEN in the IF → THEN model.
Overview
Actions are the building blocks of rules. Each action:
- Executes a single function (built-in or custom)
- Can have a condition for conditional execution
- Can modify message data
- Records changes in the audit trail
Action Structure
{
"id": "apply_discount",
"name": "Apply Discount",
"condition": { ">=": [{"var": "data.order.total"}, 100] },
"continue_on_error": false,
"function": {
"name": "map",
"input": {
"mappings": [
{
"path": "data.order.discount",
"logic": {"*": [{"var": "data.order.total"}, 0.1]}
}
]
}
}
}
Fields
| Field | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Unique action identifier within rule |
name | string | No | Human-readable name |
condition | JSONLogic | No | When to execute action (evaluated against full context) |
continue_on_error | boolean | No | Continue rule on failure |
function | object | Yes | Function to execute |
Creating Actions Programmatically
#![allow(unused)]
fn main() {
use dataflow_rs::{Action, FunctionConfig};
let action = Action::action(
"apply_discount",
"Apply Discount",
function_config,
);
}
Function Configuration
The function object specifies what the action does:
{
"function": {
"name": "function_name",
"input": { ... }
}
}
Built-in Functions
| Function | Purpose |
|---|---|
map | Data transformation and field mapping |
validation | Data validation with custom error messages |
filter | Pipeline control flow — halt workflow or skip task |
log | Structured logging with JSONLogic expressions |
parse_json | Parse JSON from payload into data context |
parse_xml | Parse XML string into JSON data structure |
publish_json | Serialize data to JSON string |
publish_xml | Serialize data to XML string |
Custom Functions
Register custom functions when creating the engine:
#![allow(unused)]
fn main() {
let engine = Engine::new(rules, Some(custom_functions));
}
Then reference them by name in actions:
{
"function": {
"name": "my_custom_function",
"input": { ... }
}
}
Conditional Execution
Actions can have conditions that determine if they should run. Conditions evaluate against the full context (data, metadata, temp_data):
{
"id": "premium_greeting",
"condition": { "==": [{"var": "data.tier"}, "premium"] },
"function": {
"name": "map",
"input": {
"mappings": [
{"path": "data.greeting", "logic": "Welcome, VIP member!"}
]
}
}
}
Common Patterns
// Only if field exists
{"!!": {"var": "data.email"}}
// Only if field equals value
{"==": [{"var": "data.status"}, "active"]}
// Only if numeric condition
{">=": [{"var": "data.amount"}, 100]}
// Combine conditions
{"and": [
{"!!": {"var": "data.email"}},
{"==": [{"var": "data.verified"}, true]}
]}
Error Handling
Action-Level Error Handling
{
"id": "optional_action",
"continue_on_error": true,
"function": { ... }
}
When continue_on_error is true:
- Action errors are recorded in
message.errors - Rule continues to the next action
Rule-Level Error Handling
The rule’s continue_on_error setting applies to all actions unless overridden.
Sequential Execution
Actions execute in order within a rule. Later actions can use results from earlier actions:
{
"tasks": [
{
"id": "step1",
"function": {
"name": "map",
"input": {
"mappings": [
{"path": "temp_data.intermediate", "logic": {"var": "data.raw"}}
]
}
}
},
{
"id": "step2",
"function": {
"name": "map",
"input": {
"mappings": [
{"path": "data.final", "logic": {"var": "temp_data.intermediate"}}
]
}
}
}
]
}
Try It
Want more features? Try the Full Debugger UI with step-by-step execution and rule visualization.
Try changing tier to “standard” to see different discount applied.
Best Practices
- Unique IDs - Use descriptive, unique IDs for debugging
- Single Responsibility - Each action should do one thing well
- Use temp_data - Store intermediate results in
temp_data - Conditions - Add conditions to skip unnecessary processing
- Error Handling - Use
continue_on_errorfor optional actions