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 - 输出属性的限定名称

  • 价值------通过禅宗表达语言表达的价值

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

决策节点

"决策"节点旨在扩展决策模型的功能。其功能是在执行过程中调用和重用其他决策模型。

通过合并"决策"节点,开发人员可以模块化决策逻辑,从而提高复杂系统的可重用性和可维护性。

项目点击标题 https://www.jdon.com/72453.html

相关推荐
霍先生的虚拟宇宙网络7 分钟前
webp 网页如何录屏?
开发语言·前端·javascript
温吞-ing9 分钟前
第十章JavaScript的应用
开发语言·javascript·ecmascript
彪82510 分钟前
第十章 JavaScript的应用 习题
javascript·css·ecmascript·html5
Myli_ing2 小时前
考研倒计时-配色+1
前端·javascript·考研
余道各努力,千里自同风2 小时前
前端 vue 如何区分开发环境
前端·javascript·vue.js
PandaCave2 小时前
vue工程运行、构建、引用环境参数学习记录
javascript·vue.js·学习
软件小伟2 小时前
Vue3+element-plus 实现中英文切换(Vue-i18n组件的使用)
前端·javascript·vue.js
醉の虾2 小时前
Vue3 使用v-for 渲染列表数据后更新
前端·javascript·vue.js
张小小大智慧2 小时前
TypeScript 的发展与基本语法
前端·javascript·typescript
疯狂的沙粒3 小时前
对 TypeScript 中高级类型的理解?应该在哪些方面可以更好的使用!
前端·javascript·typescript