10 个版本 (6 个重大更改)

0.26.0 2024年8月8日
0.25.0 2024年8月7日
0.24.3 2024年8月1日
0.24.2 2024年7月17日
0.20.1 2024年4月3日

#41模板引擎

Download history 17/week @ 2024-04-29 13/week @ 2024-05-06 183/week @ 2024-05-13 162/week @ 2024-05-20 61/week @ 2024-05-27 35/week @ 2024-06-03 28/week @ 2024-06-10 24/week @ 2024-06-17 54/week @ 2024-06-24 125/week @ 2024-07-01 24/week @ 2024-07-08 363/week @ 2024-07-15 12/week @ 2024-07-22 175/week @ 2024-07-29 272/week @ 2024-08-05 33/week @ 2024-08-12

每月下载量 494
zen-engine 中使用

MIT 许可证

215KB
5K SLoC

License: MIT

业务规则引擎

ZEN 引擎是一个跨平台的开源业务规则引擎(BRE)。它用 Rust 编写,并为 NodeJSPythonGo 提供了原生绑定。ZEN 引擎可以从 JSON 文件中加载和执行 JSON 决策模型(JDM)

Open-Source Rules Engine

我们 JDM 编辑器 仓库提供了一个开源的 React 编辑器。

使用方法

ZEN 引擎被构建为可嵌入的业务规则引擎,用于您的 RustNodeJSPythonGo 应用程序。它从 JSON 内容解析 JDM。您需要自行获取 JSON 内容,例如从文件系统、数据库或服务调用。

支持的平台

Zen 引擎原生可用的平台列表

完整的 业务规则管理系统(BRMS) 解决方案

Rust

[dependencies]
zen-engine = "0"
use serde_json::json;
use zen_engine::DecisionEngine;
use zen_engine::model::DecisionContent;

async fn evaluate() {
    let decision_content: DecisionContent = serde_json::from_str(include_str!("jdm_graph.json")).unwrap();
    let engine = DecisionEngine::default();
    let decision = engine.create_decision(decision_content.into());

    let result = decision.evaluate(&json!({ "input": 12 })).await;
}

更多高级用例,请访问Rust 文档

JSON 决策模型(JDM)

GoRules JDM(JSON 决策模型)是一个建模框架,旨在简化决策模型的表示和实现。

了解 GoRules JDM

在核心上,GoRules JDM 围绕决策模型的概念,这些模型以 JSON 格式存储的相互连接的图。这些图捕捉了 GoRules Zen-Engine 中各个决策点、条件和结果之间的复杂关系。

通过将节点与边连接起来创建图,边充当从节点到节点(通常是从左到右)移动信息路径。

输入节点作为所有与上下文相关的数据的入口,而输出节点生成决策过程的输出结果。数据从输入节点到输出节点的流动路径,遍历所有相互连接的节点。当数据通过这个网络流动时,在每个节点都会进行评估,连接决定数据沿着图传递的位置。

要查看 JDM 图的实际操作,可以使用带有内置模拟器的免费在线编辑器

除了图输入节点(请求)和输出节点(响应)外,还有5种主要节点类型

  • 决策表节点
  • 切换节点
  • 函数节点
  • 表达式节点
  • 决策节点

决策表节点

概述

表格以结构化的方式表示决策过程,允许开发人员和业务用户以清晰简洁的方式表达复杂的规则。

Decision Table

结构

决策表的核心是其模式,它定义了结构,包括输入和输出。输入包括使用 ZEN 表达语言编写的面向业务的表达式,容纳了各种条件,如相等、数值比较、布尔值、日期时间函数、数组函数等。模式输出规定了决策表生成结果的格式。输入和输出通过用户友好的界面表达,通常类似于电子表格。这便于修改和添加规则,使业务用户能够参与决策逻辑,而无需深入了解复杂的代码。

评估过程

决策表按行从上到下评估,遵循指定的命中策略。通过输入列评估单行,从左到右。每个输入列代表 AND 操作符。如果单元格为空,则该列按 值评估,独立于该值。

如果行中的单个单元格失败(由于错误或其他原因),则跳过该行。

命中策略

命中策略确定基于匹配规则的输出计算。

评估结果为

  • 一个对象,如果决策表的命中策略为 first 且有规则匹配。结构由输出字段定义。带有点(.)内部的合格字段名导致嵌套对象。
  • null/undefined,如果没有规则在 first 命中策略中匹配
  • 一个对象数组,如果决策表的命中策略为 collect(每个匹配规则一个数组项)或空数组,如果没有规则匹配

输入

在规则或行的评估中,输入列体现 AND 操作符。值通常由(合格)名称组成,例如 customer.countrycustomer.age

输入有两种评估类型,UnaryExpression

一元评估

一元评估通常用于当我们想单独比较传入上下文中的单个字段时,例如 customer.countrycart.total 。当列在其模式中定义了 field 时,它会激活。

示例

对于输入

{
  "customer": {
    "country": "US"
  },
  "cart": {
    "total": 1500
  }
}
Decision Table Unary Test

此评估转换为

IF customer.country == 'US' AND cart.total > 1000 THEN {"fees": {"percent": 2}}
ELSE IF customer.country == 'US' THEN {"fees": {"flat": 30}}
ELSE IF customer.country == 'CA' OR customer.country == 'MX' THEN {"fees": {"flat": 50}}
ELSE {"fees": {"flat": 150}}

列表展示了输入字段中一元测试的基本示例

输入条目 输入表达式
"A" 字段等于"A"
"A", "B" 字段是"A"或"B"
36 数值等于36
< 36 小于36的值
> 36 大于36的值
[20..39] 在20到39之间(包括)的值
20,39 等于20或39的值
<20, >39 小于20或大于39的值
true 布尔值true
false 布尔值false
任何值,甚至是null/undefined
null 值null或undefined

注意:有关完整列表,请访问ZEN表达式语言

表达式评估

表达式评估用于我们希望在单个单元格内创建更复杂的评估逻辑时。它允许我们在同一单元格内比较传入上下文中的多个字段。

可以通过在列配置中提供一个空的 Selector (field) 来使用它。

示例

对于输入

{
  "transaction": {
    "country": "US",
    "createdAt": "2023-11-20T19:00:25Z",
    "amount": 10000
  }
}
Decision Table Expression
IF time(transaction.createdAt) > time("17:00:00") AND transaction.amount > 1000 THEN {"status": "reject"}
ELSE {"status": "approve"}

注意:有关完整列表,请访问ZEN表达式语言

输出

输出列是决策表在评估期间满足条件时要生成数据的蓝图。

当决策表的某一行满足其指定的条件时,输出列确定返回信息的性质和结构。每个输出列代表一个不同的字段,这些字段的集合构成了与验证行关联的输出或结果。这种机制允许决策表精确地定义和控制数据输出。

示例

Decision Table Output

结果将是

{
  "flatProperty": "A",
  "output": {
    "nested": {
      "property": "B"
    },
    "property": 36
  }
}

切换节点(NEW)

GoRules JDM中的切换节点引入了一种动态分支机制,使决策模型可以根据条件发散。

条件以Zen表达式语言编写。

通过整合切换节点,决策模型变得更加灵活和上下文感知。这种能力在需要根据不同的输入执行多样化决策逻辑的情况下特别有价值。切换节点有效地管理图中的分支,增强了GoRules JDM中决策模型的复杂性和现实性,使其成为构建智能和自适应系统的关键组件。

切换节点不会修改传入的数据;它将整个上下文转发到输出分支(es)。

Switch / Branching

命中策略

切换节点有两种HitPolicy选项,firstcollect

在首次命中策略的上下文中,图分支到第一个匹配条件,类似于表中的行为。相反,在收集命中策略下,图扩展到所有条件为真的分支,允许分支到多个路径。

注意:如果有来自同一条件的多个边,则没有保证执行顺序。

可用自

  • Python 0.16.0
  • NodeJS 0.13.0
  • Rust 0.16.0
  • Go 0.1.0

函数节点

函数节点是JavaScript片段,允许快速轻松地使用JavaScript解析、重映射或以其他方式修改数据。节点的输入作为函数的参数提供。函数在包含在ZEN引擎中的QuickJS引擎上执行。

函数超时设置为50ms。

const handler = (input, {dayjs, Big}) => {
    return {
        ...input,
        someField: 'hello'
    };
};

存在两个内置库

  • dayjs - 用于日期操作
  • big.js - 用于任意精度小数运算。

表达式节点

表达式节点用作将输入对象转换为替代对象(使用禅表达式语言)的工具。在指定输出属性时,每个属性都需要单独一行。这些行由两个字段定义

  • 键 - 输出属性的限定名称
  • 值 - 通过禅表达式语言表达的价值

注意:表达式节点中的任何错误都会使图停止。

Decision Table

决策节点

“决策”节点旨在扩展决策模型的功能。其功能是在执行期间调用和重用其他决策模型。

通过引入“决策”节点,开发者可以对决策逻辑进行模块化,从而提高复杂系统的可重用性和可维护性。

支持矩阵

架构 Rust NodeJS Python Go
linux-x64-gnu ✔️ ✔️ ✔️ ✔️
linux-arm64-gnu ✔️ ✔️ ✔️ ✔️
darwin-x64 ✔️ ✔️ ✔️ ✔️
darwin-arm64 ✔️ ✔️ ✔️ ✔️
win32-x64-msvc ✔️ ✔️ ✔️ ✔️

目前我们不支持linux-musl。

贡献

JDM标准正在发展,我们需要对其发展和路线图保持严格控制,因为有多个公司正在使用GoRules Zen-Engine和GoRules BRMS。因此,我们现在不能接受任何代码贡献,除了帮助编写文档和进行额外的测试。

许可证

MIT许可证

依赖项

~3.5–5MB
~88K SLoC