GoRules:Go的业务规则引擎


ZEN Engine 是一个跨平台、开源业务规则引擎 (BRE)。它是用 Rust 编写的,并提供NodeJS、Python和Go的本机绑定。 ZEN Engine 允许从 JSON 文件加载和执行 JSON 决策模型 (JDM)。

我们的JDM Editor存储库上提供了开源 React 编辑器。

安装
go get github.com/gorules/zen-go

用法
ZEN Engine 构建为可嵌入的 BRE,适用于您的Rust、NodeJS、Python或Go应用程序。它从 JSON 内容解析 JDM。您可以自行决定是否从文件系统、数据库或服务调用中获取 JSON 内容。

加载并执行规则

package main

import (
    "fmt"
    
"os"
    
"path"
)

func readTestFile(key string) ([]byte, error) {
    filePath := path.Join(
"test-data", key)
    return os.ReadFile(filePath)
}

func main() {
    engine := zen.NewEngine(zen.EngineConfig{Loader: readTestFile})
    defer engine.Dispose()
// Call to avoid leaks

    output, err := engine.Evaluate(
"rule.json", map[string]any{})
    if err != nil {
        fmt.Println(err)
    }

    fmt.Println(output)
}

有关规则格式和高级用法的更多详细信息,请查看文档

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

了解 GoRules JDM
GoRules JDM 的核心围绕决策模型的概念,即以 JSON 格式存储的互连图。这些图表捕获了 GoRules Zen 引擎中各种决策点、条件和结果之间的复杂关系。

图是通过将节点与边连接起来而形成的,这些边就像将信息从一个节点移动到另一个节点(通常是从左到右)的路径。

输入节点充当与上下文相关的所有数据的入口,而输出节点则产生决策过程的结果。数据的传输遵循从输入节点到输出节点的路径,遍历其间所有互连的节点。当数据流经该网络时,它会在每个节点处进行评估,并且连接决定数据沿着图传递的位置。

要查看 JDM Graph 的实际效果,您可以使用带有内置模拟器的免费在线编辑器。

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

  • 决策表节点
  • 切换节点
  • 功能节点
  • 表达节点
  • 决策节点

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

结构
决策表的核心是它的模式,用输入和输出定义结构。输入包括使用 ZEN 表达式语言的业务友好表达式,适应一系列条件,例如相等、数字比较、布尔值、日期时间函数、数组函数等。该模式的输出规定了决策表生成的结果的形式。输入和输出通过用户友好的界面表示,通常类似于电子表格。这有助于轻松修改和添加规则,使业务用户能够为决策逻辑做出贡献,而无需深入研究复杂的代码。

评估流程
决策表从上到下逐行评估,遵循指定的命中策略。单行通过输入列从左到右进行评估。每个输入列代表AND运算符。如果单元格为空,则该列将被真实评估,与值无关。

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

命中策略
命中策略根据匹配规则确定结果计算。

评估结果为:

  • 如果决策表的命中策略first与规则匹配,则为对象。该结构由输出字段定义。内部带有点 (.) 的限定字段名称会导致嵌套对象。
  • null/undefinedfirst如果命中策略中没有匹配的规则
  • 如果决策表的命中策略是(collect每个匹配规则一个数组项),则为对象数组;如果没有规则匹配,则为空数组

输入
在规则或行的评估中,输入列体现了AND运算符。这些值通常由(限定)名称组成,例如customer.country或customer.age。

输入的评估有两种类型,Unary和Expression。

一元评估
当我们想要分别比较传入上下文中的单个字段时,通常使用一元求值,例如customer.country和cart.total。当列field在其模式中定义时,它被激活。

例子

对于输入:

{
  "customer": {
   
"country": "US"
  },
 
"cart": {
   
"total": 1500
  }
}

这个评估转化为

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}}

表达评估
当我们想在单个单元格内创建更复杂的求值逻辑时,可以使用表达式求值。它允许我们比较同一单元格内传入上下文的多个字段。
可以通过提供空的内部列配置来使用它Selector (field)。

输出
输出列充当评估期间满足条件时决策表将生成的数据的蓝图。
当决策表中的一行满足其指定条件时,输出列确定将返回的信息的性质和结构。每个输出列代表一个不同的字段,这些字段的集合形成与已验证行关联的输出或结果。这种机制允许决策表精确定义和控制数据输出。

切换节点(新)
GoRules JDM 中的 Switch 节点向决策模型引入了动态分支机制,使图能够根据条件发散。

条件是用 Zen 表达式语言编写的。

通过合并 Switch 节点,决策模型变得更加灵活和上下文感知。在需要基于不同输入的不同决策逻辑的场景中,此功能特别有价值。 Switch 节点有效地管理图中的分支,增强 GoRules JDM 中决策模型的整体复杂性和现实性,使其成为构建智能和自适应系统的关键组件。

Switch节点保留传入的数据而不做任何修改;它将整个上下文转发到输出分支。

命中策略
切换节点有两个 HitPolicy 选项,first和collect。
在首次命中策略的上下文中,图分支到初始匹配条件,类似于在表中观察到的行为。相反,在收集命中策略下,该图扩展到条件成立的所有分支,从而允许分支到多个路径。
注意:如果同一条件有多个边,则不保证执行顺序。


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

函数超时设置为 50ms。

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

有两个内置库:
  • dayjs - 用于日期操作
  • big.js - 用于任意精度的十进制算术。

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

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

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

决策节点
“决策”节点旨在扩展决策模型的功能。其功能是在执行过程中调用和重用其他决策模型。
通过合并“决策”节点,开发人员可以模块化决策逻辑,从而提高复杂系统的可重用性和可维护性。

项目点击标题