Lightweight and fast rule engine written in Go, with API for other languages:
- Go (this!)
- Java
With Rulestone you can define thousands of rules and then process tens of thousands events/objects per second getting the matching rules for each object.
Install the package:
go get github.com/atlasgurus/rulestone
The following Go example shows how to load a rule from file and match an object against this rule:
package main
import (
"fmt"
"github.com/atlasgurus/rulestone/utils"
"github.com/atlasgurus/rulestone/engine"
)
func Match() {
repo := engine.NewRuleEngineRepo()
_, err := repo.RegisterRuleFromFile("rule.json")
if err != nil {
return
}
ruleEngine, err := engine.NewRuleEngine(repo)
if err != nil {
return
}
event, err := utils.ReadEvent("object.json")
if err != nil {
return
}
matches := ruleEngine.MatchEvent(event)
for _, ruleId := range matches {
// Optionally get matching rules metadata
ruleDefinition := ruleEngine.GetRuleDefinition(ruleId)
if ruleIdStr, ok := ruleDefinition.Metadata["rule_id"].(string); ok {
fmt.Println("Rule matched: ", ruleIdStr)
}
}
// Report all the errors if any
if repo.GetAppCtx().NumErrors() > 0 {
repo.GetAppCtx().PrintErrors()
}
}
func main() {
Match()
}
The example assumes rule contains the metadata field called rule_id
.
See for more Go usage examples in tests/rule_api_test.go
.
metadata:
created: "2023-03-29"
priority: 10
rule_id: "BUSINESS_RULE_1"
expression: name == "Frank" && age == 20
The rule match if the JSON object has a name
field with value Frank
and an age
field with value 20
.
The metadata section may store any information linked to the rule, including the rule ID.
The condition section contains the expression that will be evaluated against the JSON object.
See examples/rules
for more rules examples.
Rulestone expressions supports:
-
Comparison and negation operators like
==
,>
,>=
,<
,<=
-
Arithmetic operations:
+
,-
,*
,/
-
Logical operators:
&&
,||
,!
-
Parentheses:
(
,)
-
String literals:
"string"
-
Numeric literals:
1
,2.3
-
Field access:
field1
,field1.field2
-
Functions:
hasValue
,isEqualToAny
,regexpMatch
,date
-
Date literals:
date("11/29/1968")
-
Date comparison operators:
<
,<=
,>
,>=
,==
-
Date arithmetic operations:
+
,-
-
hasValue
- check that object has specified field, for examplehasValue(field1)
-
isEqualToAny
- check that object field is equal to any specified value, for exampleisEqualToAny(field1, 1, 2, 3, '4')
-
regexpMatch
- match the Go regexp, for exampleregexpMatch("^\\d{4}/\\d{2}/\\d{2}$", child.dob)
Rulestone handles dates and comparison operators on them, but since JSON doesn't provide field type information,
need to use date()
function. The function can parse date string in different formats:
metadata:
created: "2023-03-29"
priority: 10
expression: 'name == "Frank" && date(dob) < date(child.dob) && date("11/29/1968") > date(dob) && date(dob) == date("11/28/1968")'
We love contributions! If you have any suggestions, bug reports, or feature requests, please open an issue in our tracker.
This project is licensed under the MIT License - see the LICENSE file for details.