Expr Reference
Expr is a lightweight expression language for simple transformations. An Expr step evaluates a single expression and returns its value as the step output.
Use Expr when you don't need loops or custom functions. Use Lark when you do.
The Basics
An Expr step contains a single expression — an object, array, scalar, or function call:
- expr: build_response
code: |
{
"total": len(step_0),
"has_data": len(step_0) > 0
}
The result of the expression becomes the step output. There is no result = assignment — the expression itself is the result.
Building Objects
- expr: shape_response
code: |
{
"user_id": input.user_id,
"org_id": input.org_id,
"row_count": len(step_0),
"first_row": step_0
}
Nest objects freely:
- expr: nested
code: |
{
"meta": {
"total": len(step_0),
"page": input.page
},
"data": step_0
}
Accessing Variables
| Variable | Description |
|---|---|
input.field | Field from request body or query param |
step_0 | Result of first logic step |
step_1 | Result of second logic step |
step_N | Result of Nth step (zero-indexed) |
- expr: example
code: |
{
"requested_by": input.user_id,
"results": step_0,
"count": len(step_0)
}
Operators
Comparison
| Operator | Meaning | Example |
|---|---|---|
== | Equal | input.role == "admin" |
!= | Not equal | input.status != "inactive" |
> | Greater than | len(step_0) > 0 |
< | Less than | len(step_0) < 10 |
>= | Greater than or equal | input.age >= 18 |
<= | Less than or equal | input.count <= 50 |
Logical
| Operator | Meaning | Example |
|---|---|---|
&& | AND | len(step_0) > 0 && input.active == true |
|| | OR | input.role == "admin" || input.role == "power" |
! | NOT | !input.disabled |
Arithmetic
| Operator | Example |
|---|---|
+ | input.count + 1 |
- | input.total - input.used |
* | input.price * input.qty |
/ | input.total / input.count |
Built-in Functions
| Function | Description | Example |
|---|---|---|
len(x) | Length of array or string | len(step_0) → 42 |
Conditional Expression
Use a ternary expression for inline conditionals:
- expr: check
code: |
len(step_0) > 0 ? step_0 : {}
- expr: status
code: |
{
"status": len(step_0) > 0 ? "found" : "not_found",
"data": len(step_0) > 0 ? step_0 : []
}
Accessing Nested Fields
# If step_0 = {"user": {"id": 1, "name": "Alice"}}
- expr: nested_access
code: |
{
"user_name": step_0["user"]["name"]
}
Common Patterns
Return all rows with metadata
- expr: with_meta
code: |
{
"total": len(step_0),
"data": step_0
}
Return first row only
- expr: first_only
code: |
len(step_0) > 0 ? step_0 : {}
Pass input fields into response
- expr: echo_input
code: |
{
"requested_by": input.user_id,
"filter_used": input.status,
"results": step_0
}
Boolean check
- expr: availability
code: |
{
"has_results": len(step_0) > 0,
"count": len(step_0)
}
Expr vs Lark
| Need | Use |
|---|---|
| Build a response object | Expr |
| Count or check length | Expr |
| Inline conditional | Expr |
| Loop over rows | Lark |
| Define a function | Lark |
| String manipulation | Lark |
| Complex multi-step transform | Lark |
When in doubt — if it fits in one expression, use Expr. If you need more than one line of logic, use Lark.