BMEL — BizMetry Expression Language¶
BMEL (BizMetry Expression Language) is a typed expression language used inside the Business Event mapper to define computed or multi-source field mappings. It allows you to write expressions that combine, transform, or conditionally select values from one or more API payload fields and assign the result to a target Frame component.
BMEL expressions are authored in the Monaco-based BMEL Editor, which provides syntax highlighting, inline validation, type inference, and source field auto-completion.
Note
BMEL has no infix operators (no +, ==, &&, and so on). Every operation — arithmetic, comparison, string manipulation, type conversion — is a named function in the bmel: namespace, called with named arguments: bmel:functionName(argName: value, ...).
When to Use BMEL¶
Use BMEL when a simple 1-to-1 field mapping is not sufficient:
| Scenario | Example |
|---|---|
| Concatenate two source fields | bmel:concat({op:Response}.$.firstName, " ", {op:Response}.$.lastName) |
| Arithmetic on a numeric field | bmel:round({op:Response}.$.totalCents / 100.0, decimals: 2) |
| Conditional value selection | bmel:if(cond: {op:Response}.$.status == "SUCCESS", a: 1, b: 0) |
| Extract a nested JSON value | bmel:json-path({op:Response}.$.payload, "$.items[0].price") |
| Type conversion | bmel:toString({op:Request}.$.orderId) |
| Default value fallback | bmel:coalesce({op:Response}.$.region, "UNKNOWN") |
Source Field Syntax¶
All source field references in BMEL use the canonical format:
{operationName:Section Label}.$.fieldPath
Examples:
{getOrder:Response Payload}.$.total_amount
{placeOrder:Request Payload}.$.customer.address.city
{getProduct:URI Parameters}.$.productId
{createAccount:Request Headers}.$.X-Tenant-Id
The BMEL editor shows only the fields you connected in the mapper — not the full schema. Unconnected fields are not available as expression inputs.
Type System¶
BMEL is statically typed with type inference. The editor validates types at authoring time and reports errors inline.
| BMEL Type | Description | Example values |
|---|---|---|
bmel:string | Text values | "hello", "USD" |
bmel:integer | Whole numbers | 42, -7 |
bmel:number | Decimal or whole numbers | 3.14, 99.99 |
bmel:boolean | True/false | true, false |
bmel:array<T> | Ordered list of items of type T | bmel:array<number> |
bmel:date | Calendar date, no time component | 2026-07-16 |
bmel:datetime | Date and time with timezone | 2026-07-16T14:30:00Z |
bmel:time | Time of day, no date component | 14:30:00 |
bmel:enum | A value from a predefined, ordered set of constants declared on a Frame component's attribute (e.g. an order status enum) | "SHIPPED" |
bmel:expression | A sub-expression evaluated lazily or repeatedly rather than once up front — used for arguments like a switch branch's result or a forRange loop body | any expression |
bmel:any | Untyped value (used for JSON payloads and generic arguments) | any value |
Type mismatches produce warnings (not hard errors) in most cases — BizMetry attempts best-effort coercion at runtime, but explicit conversion functions (bmel:toString, bmel:toNumber, bmel:toBoolean) are recommended.
Function Reference¶
BMEL ships with 110 functions across 9 categories — string, math, array & statistics, logic & control flow, date & time, JSON, type conversion, AI utilities, and LLM & AI observability. The full list, with signatures and examples, lives in the Function Reference.
A representative sample:
| Function | Signature | Description |
|---|---|---|
bmel:concat | bmel:concat(values: bmel:any...) → bmel:string | Concatenates two or more values into a string. |
bmel:upper / bmel:lower | bmel:upper(s: bmel:string) → bmel:string | Converts a string to uppercase or lowercase. |
bmel:if | bmel:if(cond: bmel:boolean, a: bmel:any, b: bmel:any) → bmel:any | Returns a if cond is true, otherwise b. |
bmel:coalesce | bmel:coalesce(values: bmel:any...) → bmel:any | Returns the first non-null value. |
bmel:switch | bmel:switch(subject, case, result, [otherwise]) → bmel:any | Evaluates subject against one or more case/result pairs and returns the first match. |
bmel:round | bmel:round(expr: bmel:number, decimals: bmel:integer) → bmel:number | Rounds to the specified number of decimal places. |
bmel:sum / bmel:avg | bmel:sum(array: bmel:array<number>) → bmel:number | Aggregates values across a mapped array column. |
bmel:toString / bmel:toNumber / bmel:toBoolean | bmel:toString(expr: bmel:any) → bmel:string | Explicit type conversion. |
bmel:json-path | bmel:json-path(json: bmel:any, path: bmel:string) → bmel:any | Extracts a value from a JSON payload by path. |
BMEL Editor¶
The BMEL Editor opens as a dialog when you click the ƒ icon on a connector line in the mapping canvas.
Editor panels¶
- Left — Expression editor: Monaco-based editor with BMEL syntax highlighting, bracket matching, and error markers.
- Right — Available source fields: Lists only the fields connected in the mapper for this target component, shown with their canonical
{op:Section}.$.pathreferences. Click any field to insert it at the cursor position.
Inline validation¶
The editor validates your expression as you type:
- Red underline — syntax error or unknown function.
- Yellow underline — type mismatch warning.
- Green checkmark — expression is valid and ready to save.
Saving a malformed expression is blocked until all errors are resolved.
Expression Examples¶
// Direct field reference
{getOrder:Response Payload}.$.order_id
// Concatenation
bmel:concat({getOrder:Response Payload}.$.firstName, " ", {getOrder:Response Payload}.$.lastName)
// Conditional
bmel:if(cond: {placeOrder:Response Payload}.$.status == "SUCCESS", a: 1, b: 0)
// Null coalescing
bmel:coalesce({getOrder:Response Payload}.$.region, "GLOBAL")
// Aggregation over a mapped array column
bmel:sum({getOrder:Response Payload}.$.lineItems.amount)
// Type conversion
bmel:toNumber({getOrder:Response Payload}.$.totalCents)
// Extracting a nested value from a JSON payload
bmel:json-path({getOrder:Response Payload}.$.payload, "$.payment.card.last4")