2

I have to build a dynamic rules engine in say, Java, where a user can define a certain list of filters and trigger a certain event based on them. The rules will be a long chain of conditions, such as:

if 
    condition1 AND (condition2 OR condition3) AND condition4
then
    trigger(event)

where conditionN is any operation based on the attribute for a business object. Example: a string can have an operation - endsWith or a number can have operations greaterThan.

The problem is, this list of rules will not be hard-coded and has to be fetched dynamically from a database (a separate web UI will update this database with the rules) and run against an entity and then trigger the appropriate action on the entity.

What's the best way to approach this kind of problem and write a scalable and high-performant program for this?

I am currently thinking of building expressions in Spring Expression Language (SpEL) and storing them in DB as strings and then while running the program, fetching this column and running them against my domain object.

// Fetch rule and action from DB
rule = rs.getString("rule"); // Rule in SpEL
action = rs.getString("action"); // Action method name

ExpressionParser parser = new SpelExpressionParser();

Expression exp = parser.parseExpression(rule);
boolean result = (String) exp.getValue(obj, Boolean.class); // Run expression against domain object `obj`

if (result) action();

I am currently not sure if this is the best way for doing things and if it will scale and be extensively customizable or not.

For the above approach, then rule string needs to built by parsing user input. I was also thinking about storing rules as an XML document:

<Rule>
    <Filter>
        <Operation name="or">
            <Operand>
                <Operation name="lessThan">
                    <Operand>${numAttribute}</operand>
                    <Operand unit="percentage">5.05</operand>
                </Operation>
            </Operand>
            <Operand>
                <Operation name="equals">
                    <Operand>${stringAttribute}</Operand>
                    <Operand>IN</Operand>
                </Operation>
            <Operand>
        </Operation>
    </Filter>
    <Action>
        actionName
    </Action>
</Rule>

However, with this scenario, I am not sure how to proceed after parsing the XML and how to run the operations dynamically based on the described values.

I would appreciate any ideas of the aforementioned ones or a totally new way to solve this problem. I understand it's a huge application but need clarity on how to start. I believe the biggest problem is how to run user inputs statements as Java code? I know a little bit about reflection but I am not sure if it's meant to solve this problem and if it should be used considering it has its drawbacks in areas of performance.

9
  • 1
    Consider your users. Unless those users are software engineers or otherwise have a great deal of programming experience, it's highly unlikely that they will have the technical background necessary to cope with the syntax that you're proposing in your XML document or be able to debug it if it breaks. On the other hand, if they are software engineers or they do have programming experience they will probably be extremely irritated about needing to write the rules in XML instead of just being able to write them in a popular, well-known mainstream programming language like Java instead. Feb 1 '20 at 22:47
  • To put it another way, your attempt at solving this problem looks like you're just writing your own programming language, yet using a far less programmer-friendly syntax. When writing a new language you need to consider maintainability of the source that your users are going to write - for example, how will they version-control it? how will they run automated tests against the logic? how will they debug faults? how will they monitor failures? What about an IDE to help write the code? etc. All-in-all, you are probably just better off using an existing programming language instead. Feb 1 '20 at 22:50
  • Instead of going to all the effort to write a whole new language for your rules, perhaps consider just releasing an API or SDK and encouraging users to use that with some popular/existing language like Python/Java instead. Feb 1 '20 at 22:58
  • (1/2) @BenCottrell Thanks for responding. Apologies if I didn't explain the use case properly. The rule engine does not require hand programming by hand. I want to have a web UI which takes HTML forms with dropdowns, take chain of operations that result in boolean output, generate a runnable expression and store it in DB. During runtime, the rule is read from DB, evaluated against the current object and if true does something on the object and if false, does something else.
    – int-main
    Feb 2 '20 at 5:12
  • 1
    Why must the list of rules not be hard coded? Hard coded rules can still be changed, you just have to re deploy the application when you make the change. The most successful organisations seem to be deploying applications to production many times per day.
    – bdsl
    Feb 2 '20 at 10:05
1

After using two rules engine implementations, I would say Don't go down this path.

Simply create a library that incapsulates the rules as a . jar file and import it into the applications that need to access those rules.

In my experience this is the simple, fast and efficient method of implementing business rules.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.