Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

JSONLogic Rules

How Reframe uses JSONLogic for business rules and field transformations.

What is JSONLogic?

JSONLogic is a standard for expressing business logic as JSON. It provides:

  • Portable rules: Same rules work across languages and platforms
  • Human-readable: Logic expressed in familiar JSON structure
  • Safe evaluation: No arbitrary code execution
  • Testable: Rules can be validated independently

Reframe uses Datalogic, a high-performance Rust implementation of JSONLogic with 59 built-in operators.

Basic Syntax

JSONLogic expressions follow this pattern:

{ "operator": [arguments] }

Variable Access

Read data from the message context:

{"var": "data.SwiftMT.fields.20.transaction_reference"}

This accesses:

data
└── SwiftMT
    └── fields
        └── 20
            └── transaction_reference → "REF123456"

Comparison

{"==": [{"var": "data.field"}, "expected_value"]}
{"!=": [{"var": "data.field"}, "unexpected_value"]}
{">": [{"var": "data.amount"}, 10000]}
{">=": [{"var": "data.amount"}, 0]}

Boolean Logic

{"and": [condition1, condition2]}
{"or": [condition1, condition2]}
{"!": [condition]}
{"!!": [value]}  // Convert to boolean

Common Transformation Patterns

Direct Mapping

Copy a value from source to target:

{
  "path": "data.output.InstrId",
  "logic": {"var": "data.SwiftMT.fields.20.transaction_reference"}
}

Conditional Mapping

Map different values based on conditions:

{
  "path": "data.output.ChrgBr",
  "logic": {
    "if": [
      {"==": [{"var": "data.SwiftMT.fields.71A.details_of_charges"}, "SHA"]},
      "SHAR",
      {"if": [
        {"==": [{"var": "data.SwiftMT.fields.71A.details_of_charges"}, "OUR"]},
        "DEBT",
        "CRED"
      ]}
    ]
  }
}

Default Values

Provide fallback when source is missing:

{
  "path": "data.output.PmtTpInf.SvcLvl.Cd",
  "logic": {
    "or": [
      {"var": "data.SwiftMT.fields.23B.bank_operation_code"},
      "G001"
    ]
  }
}

String Concatenation

Combine multiple fields:

{
  "path": "data.output.FullName",
  "logic": {
    "cat": [
      {"var": "data.first_name"},
      " ",
      {"var": "data.last_name"}
    ]
  }
}

String Extraction

Extract portions of a string:

{
  "path": "data.output.CountryCode",
  "logic": {
    "substr": [
      {"var": "data.SwiftMT.fields.50K.account"},
      0,
      2
    ]
  }
}

Array Operations

Map (Transform Each Element)

{
  "map": [
    {"var": "data.items"},
    {"cat": ["Item: ", {"var": ""}]}
  ]
}

Filter

{
  "filter": [
    {"var": "data.transactions"},
    {">": [{"var": "amount"}, 1000]}
  ]
}

Reduce (Aggregate)

{
  "reduce": [
    {"var": "data.amounts"},
    {"+": [{"var": "accumulator"}, {"var": "current"}]},
    0
  ]
}

Check All/Some/None

{"all": [{"var": "data.items"}, {"!!": {"var": "valid"}}]}
{"some": [{"var": "data.items"}, {"==": [{"var": "status"}, "active"]}]}
{"none": [{"var": "data.items"}, {"<": [{"var": "amount"}, 0]}]}

Object Construction

Create Objects

Build complex structures:

{
  "path": "data.output.Amt",
  "logic": {
    "object": {
      "Ccy": {"var": "data.SwiftMT.fields.32A.currency"},
      "value": {"var": "data.SwiftMT.fields.32A.amount"}
    }
  }
}

Nested Objects

{
  "path": "data.output.Dbtr",
  "logic": {
    "object": {
      "Nm": {"var": "data.SwiftMT.fields.50K.name"},
      "PstlAdr": {
        "object": {
          "Ctry": {"var": "data.country"},
          "AdrLine": {"var": "data.address_lines"}
        }
      }
    }
  }
}

Date and Time Operations

Current Timestamp

{"now": []}

Format Date

{
  "format_date": [
    {"var": "data.date"},
    "%Y-%m-%d"
  ]
}

Parse Date

{
  "parse_date": [
    {"var": "data.date_string"},
    "%y%m%d"
  ]
}

Validation Rules

Use JSONLogic for validation:

{
  "id": "validate-amount",
  "function": {
    "name": "validation",
    "input": {
      "rules": [
        {
          "logic": {">": [{"var": "data.amount"}, 0]},
          "message": "Amount must be positive"
        },
        {
          "logic": {"!!": {"var": "data.currency"}},
          "message": "Currency is required"
        },
        {
          "logic": {
            "in": [
              {"var": "data.currency"},
              ["USD", "EUR", "GBP", "JPY"]
            ]
          },
          "message": "Invalid currency code"
        }
      ]
    }
  }
}

CBPR+ Rule Examples

Charge Bearer Mapping

// MT Tag 71A to ISO 20022 ChargeBearerType1Code
{
  "if": [
    {"==": [{"var": "data.SwiftMT.fields.71A.details_of_charges"}, "SHA"]},
    "SHAR",
    {"if": [
      {"==": [{"var": "data.SwiftMT.fields.71A.details_of_charges"}, "OUR"]},
      "DEBT",
      {"if": [
        {"==": [{"var": "data.SwiftMT.fields.71A.details_of_charges"}, "BEN"]},
        "CRED",
        "SHAR"
      ]}
    ]}
  ]
}

Service Level Determination

// Determine CBPR+ service level from MT fields
{
  "if": [
    {"==": [{"var": "data.SwiftMT.fields.23E.instruction_code"}, "URGP"]},
    "G001",
    {"if": [
      {"==": [{"var": "data.SwiftMT.fields.23B.bank_operation_code"}, "SPAY"]},
      "G003",
      "G002"
    ]}
  ]
}

Party Identification

// Build creditor identification from MT fields
{
  "object": {
    "Nm": {"var": "data.SwiftMT.fields.59.beneficiary_name"},
    "PstlAdr": {
      "object": {
        "AdrLine": {
          "filter": [
            {"var": "data.SwiftMT.fields.59.address_lines"},
            {"!!": {"var": ""}}
          ]
        }
      }
    },
    "Id": {
      "if": [
        {"!!": {"var": "data.SwiftMT.fields.59.account"}},
        {
          "object": {
            "OrgId": {
              "object": {
                "Othr": {
                  "object": {
                    "Id": {"var": "data.SwiftMT.fields.59.account"}
                  }
                }
              }
            }
          }
        },
        null
      ]
    }
  }
}

Testing Rules

Test rules in the Datalogic playground:

Datalogic Playground →

Example test:

// Rule
{
  "if": [
    {">": [{"var": "amount"}, 10000]},
    "HIGH",
    "NORMAL"
  ]
}

// Data
{"amount": 50000}

// Result
"HIGH"

Operator Reference

Comparison Operators

==, ===, !=, !==, >, >=, <, <=

Boolean Operators

and, or, !, !!

Numeric Operators

+, -, *, /, %, min, max, abs

String Operators

cat, substr, in, starts_with, ends_with, upper, lower, trim

Array Operators

map, filter, reduce, all, some, none, merge, sort

Control Flow

if, ?:, ??

Date/Time

now, datetime, format_date, parse_date, date_diff

Complete Operator Reference →