ZEN Engine is built as embeddable BRE for your Rust, NodeJS, Go or Python applications.

Installation

go get https://github.com/gorules/zen-go

Usage

To execute a simple decision you can use the code below.

package main

import (
	"github.com/gorules/zen-go"
	"os"
)

func main() {
	engine := zen.NewEngine(zen.EngineConfig{})

	graph, err := os.ReadFile("./jdm-graph.json")
	if err != nil {
		panic(err)
	}

	decision, err := engine.CreateDecision(graph)
	if err != nil {
		panic(err)
	}

	response, err := decision.Evaluate(map[string]any{"input": 15})
}

Loaders

For more advanced use cases where you want to load multiple decisions and utilise graphs you can build loaders.

package main

import (
	"errors"
	"github.com/gorules/zen-go"
	"os"
	"path"
)

func workingDirectory() string {
	wd, err := os.Getwd()
	if err != nil {
		panic("Unable to determine working directory")
	}

	return wd
}

func decisionLoader(key string) ([]byte, error) {
	decisionPath := path.Join(workingDirectory(), "graphs", key)
	decisionContent, err := os.ReadFile(decisionPath)
	if err != nil {
		return nil, errors.New("file not found")
	}

	return decisionContent, nil
}

func main() {
	engine := zen.NewEngine(zen.EngineConfig{
		Loader: decisionLoader,
	})

	response, err := engine.Evaluate("jdm_graph1.json", map[string]any{"input": 15})
}

or

package main

import (
	"errors"
	"github.com/gorules/zen-go"
	"os"
	"path"
)

...

func main() {
	engine := zen.NewEngine(zen.EngineConfig{
		Loader: decisionLoader,
	})

	decision, err := engine.GetDecision("jdm-graph1.json")
	if err != nil {
		panic(err)
	}
	
	response, err := engine.Evaluate("jdm_graph1.json", map[string]any{"input": 15})
}

When engine.Evaluate is invoked it will call loader and pass a key expecting a content of the JDM decision graph.
In the case above we will assume file jdm_directory/jdm_graph1.json exists.

Similar to this example you can also utilise loader to load from different places, for example from REST API, from S3, Database, etc.

Evaluate expressions

You may also evaluate singular ZEN Expressions.

package main

import "github.com/gorules/zen-go"

func main() {
	r1, err := zen.EvaluateExpression[int]("1 + 1", nil)                              // 2
	r2, err := zen.EvaluateExpression[int]("a + b", map[string]any{"a": 10, "b": 20}) // 30

	r3, err := zen.EvaluateUnaryExpression("> 10", map[string]any{"$": 5})  // false
	r4, err := zen.EvaluateUnaryExpression("> 10", map[string]any{"$": 15}) // true
}