For every business, there are a set of rules which define all actions and behaviours. Products which leverage technology for its distribution and usage may contain millions of rules, which are usually tightly coupled with multiple if-else statements within code or configuration files across services
Bonsai is a platform to store, evaluate and analyse all your business decisions/rules at a single place.
-
Bonsai Decision Service : hosts and evaluates business rules pertaining to particular namespace. Uses RedisJSON as the underlying storage for all the rules
-
Bonsai UI : Interface for authoring and previewing all business rules. Interacts with the decision service for all operations
- Loyalty Management System
- Codless API's
- Pricing System
- Insurance premium calculation
- and many more...
- Namespace
- Rules
- entity
The top most logical seperation of rules are on the basis of namespace. Namespace is one set of rules which are to be evaluated on some data. For example you will build a namespace for a loyalty management system and all the rules regarding that will be saved under that namespace.
- The structure for saving our data is
{
"tax_system": {}
}
Here namespace is : tax_system .
JSON.SET namespace_name . {}
Each Entity means the input into a namespace which inturn will give an output after evaluation of the rules present in that namespace.
- Predicates: This means the input conditions for your rules.
- Results: This means the output conditions for your rules.
- Operators: We have 7 operators :
-eqwhich means=
-rangewhich means the value should lie between the given range(upper limit not included)
-containswhich means that the string should contain the input value given.
-gtwhich means greater than or>
-gtewhich means greater than or equal to>=
-ltwhich means lesser than<
-ltewhich means lesser than or equal to<=
For example we want to create a rule to determine tax value of a citizen who has lives in province ontario and city toronto . The tax for this citizen should be 35%.
So in this case I have two variables province and city and one output tax_rate.
So in our case one example predicate(input) of province is Ontario can be
a predicate consists of 4 parts :
{
"attribute_name": "Province", # the name of your input
"operator": "eq", # type of operation
"type": "string", # type of input such as INT or STRING
"value": "Ontario" # value of the input you want to gove
}
Each rules is a command which decides what should be the output to any particular input ( entity )
Every rule gets saved into a namespace via the following format .
example used in this rule is if province is Ontario and city is Toronto the tax rate will be 35
this is the rule object:
{
"tax_system": {
"123456": {
"id": 123456,
"namespace": "tax_system",
"rule_description": "this is a test rule",
"predicates": [
{
"attribute_name": "Province",
"operator": "eq",
"type": "string",
"value": "Ontario"
},
{
"attribute_name": "City",
"operator": "eq",
"type": "string",
"value": "Toronto"
}
],
"result": {
"attribute_name": "tax_rate",
"operator": "eq",
"type": "string",
"value": "35"
}
}
}
}
Here namespace is : loyalty_system and rule_id is : 123456.
JSON.SET namespace_name .rule_id rule_object
JSON.GET namespace_name
JSON.GET namespace_name path .rule_id

A very easy to use USER EXPERIENCE to add inputs and configure outputs as seen in the gif above.

Once rule is created you can easily visualize in the form of a flow chart which makes it even easier to debug for business teams which is one of the main disadvantages of a traditional rule engine

The code uses pattern matching algorithms to see which rule fits the entity best and also emits the order in which rules were executed (in other words chained rule execution is also possible)

We have used redis Timeseries database to publish basic telemetery of rule excution and evaluation processes to give the business users capabilities to make data driven decisions on the basis of performance of rules in their namespace.
TS.ADD ruleId * 1
