Imagine you have a system with dynamic business rules, that your client wants to change on a regular basis. This rule engine is used by scheduled background processes and helps your client in terms of managing their infrastructure. 

Coincidentally your client is also using Microsoft's MSSQL as their preferred database, and your rule engine is JSON-based running on a cloud provider as a REST API, as an Azure function

So your client suggests that the rules should be stored in an MSSQL table so that they can easily create a user interface that reads and writes the business rules. To make things really easy for your client, the rules should not be expressed as JSON (the default format used by the rule engine, like this one), but instead, be persisted in a plain tabular format. After all, most GUI builders work with traditional RDBMS systems.

So you agree with your client that your JSON based rule engine is going to be fed with rules from their Microsoft's MSSQL database.

Rules Engine Architecture

So you end up with an architecture that looks like this:

These are the main components of our architecture:

The Missing Link

So this sounds like a good architecture, but something is missing. How do you bring the rules expressed in tabular format into your rules engine? 

The missing link is highlighted in a red bubble below:

A Small Framework For Saving and Retrieving Rules in a Tabular Format

We have created a small framework to bring rules in a tabular format into the format of our JSON based rule engine: the json-rules-engine.

The first thing that we needed was a representation of rules in a tabular format. To achieve this, we need first to understand what a rule and a logical condition are: 

  • a rule is a container of logical conditions that can be combined either by an OR ("any") or AND ("all") logical operators. A rule also triggers an event in case it evaluates to true.
  • a logical condition is the association of a fact (field in a data record) with an operator and a value.

Here is an example of a logical condition in JSON format:


Here is a simple rule in JSON format, which combined two logical conditions with an AND operator ("all"):

This simple rule triggers an event in case two meteorological conditions are satisfied. So if the windspeed is greater than 15 mph and the precipitation is greater than 155 mm a device is shut down.

Sometimes rules can be nested in other rules, thus allowing multiple combinations of OR and AND rules. So there is a need to have rules which have other rules as their children, like, e.g.:

The Rules Schema

It was only necessary to create two tables to represent our rules data model:

We have a rule condition entity with a many-to-one relationship to the rule definition entity. The rule definition also has a one-to-many relationship with itself, i.e. a rule definition can have multiple children, but only a single parent. 

This simple schema together with some conversion code is enough to create the JSON  rules depicted above.

The Conversion Library

The Typescript library, which converts the data in the relational schema described above to JSON, can be found in a Git repository.

If you want to convert the content of our relational rules database to a JSON file, you can execute this code:

The function createRules extracts the rules from the database into a Javascript object.

This is what the createRules function does internally:

  • It queries the database and outputs a flat list of conditions associated with their respective rules. It executes this query:

  • It then loops through the list of all conditions + rule and aggregates the conditions per rule. At the end of this process, you will have a list of rules with a list of conditions and the symbols used in the database will also have been converted to the symbols used by the json-rules-engine library.
  • It then builds the hierarchy of the rules recursively.

For more details you can check the code in our Git repository:

https://github.com/onepointconsulting/rules-deserializer/blob/master/src/ruleToFile.ts

Conclusion

Using Microsoft Azure-based technologies allows you to build powerful rules-based systems, including REST-based rule execution with workflow integration, with proper rules storage and a GUI (graphical user interface), that allows business users to create and change rules. Since most rule engines come with their own native format, you will need to convert the RDBMS based format into the native format of your rules engine. This can be achieved using a basic rules schema and the example project we presented in this blog.