RulesEspresso - A Simple Rules Engine for OutSystems Developer Cloud

Stefan WeberStefan Weber
6 min read

RulesEspresso is one of the components I published on OutSystems Developer Cloud Forge. It is a simple yet powerful rules engine that lets you define and execute business rules at runtime. While this approach isn't suitable for every use case, it offers several advantages over embedding business rules directly in the application code. The biggest benefit is that you can change business rules without redeploying the application, unlike logic built in ODC Studio. You can even let an application user create or modify business rules.

Let's consider the following scenario.

You are asked to implement a simple product discount. You need to create a discount scale that offers a discount based on membership status.

  • Bronze status members receive 2%

  • Silver status members receive 5%

  • Gold status members receive 10%

Such a discount calculation can easily be implemented in ODC with an entity containing the discounts for each membership level. However, these discount calculations can change quickly over time, and changes could include:

  • Discounts should not be applied if the product is already discounted.

  • A discount should only be applied if the product's value exceeds a certain amount.

  • A discount should only be applied if at least three items of the product are purchased.

  • or a combination of the above……

Besides these permanent or semi-permanent changes, you might also encounter temporary changes, like additional discounts during a specific timeframe or even a complete change in the discount calculation if the company updates their membership program.

In short, implementing business rules directly within an application can become a burden and you may even risk losing money if you can't adapt to changes quickly enough. Externalizing business rules is the solution, as it allows you to define and modify business rules at runtime without changing server actions and redeploying the application.

💡
Of course, even with the most advanced external rules definition, there is always a chance that you will still need to adjust the code. Business rules engines simply reduce the risk of needing to change the code.

Demo Application

This article features a demo application called "RulesEspresso Demo," available on ODC Forge.

  • In the ODC Portal, navigate to Forge - All Assets.

  • Search for "RulesEspresso Demo".

  • Click on Install.

This demo relies on:

  • RulesEspresso - This external logic library is the rules engine implementation you can use in your own applications.

RulesEspresso Introduction

RulesEspresso is a simple implementation of a business rules engine. At a glance it allows you to

  • Provide a flat property JSON document containing data as the rules evaluation context.

  • Include an optional JSON Schema for data validation.

  • Define one or more rules using C# expressions to evaluate data conditions, returning either true or false.

  • Optional result C# expressions for each rule to add calculated properties to the rules evaluation context if the rule expression evaluates to true.

💡
While this approach is suitable for many use-case scenarios, it has its limitations. In more complex situations, you might want to consider integrating with a mature business rules products (BRMS) like IBM Operational Decision Manager or Redhat Decision Manager.

Parameters

RulesEspresso external logic library contains a single action EvaluateRules with the following input parameters

dataObject

This parameter accepts a JSON document with key/value pairs that can be used in rule definitions. It serves as the context for a single run of EvaluateRules. To generate the dataObject input, you can:

  • Create a structure with attributes.

  • Use the structure as a local variable in a server action flow and assign values to it.

  • Serialize the variable using the JSON Serialize action - with Serialize Default Values set to Yes!.

  • Use the serialized result as the value for the dataObject input parameter.

💡
At the time of writing, RulesEspresso only supports flat JSON documents, which means you cannot use nested objects or arrays.

ruleDefinitions

This parameter accepts a list of individual rules. Each rule consists of:

  • RuleName - Any text. Each rule is evaluated separately, and you can use the rule name to identify it in the result of the Evaluate Rules action.

  • EvaluationExpression - A boolean C# expression. This is where you specify a condition for the rule evaluation. Attributes of the dataObject are referred to by their names, and you can use C# methods within the conditions, such as DateTime.Now.

  • ResultExpression - An optional C# expression that is evaluated if the EvaluationExpression is true. The ResultExpression can return a static or computed value, adding to the rules evaluation context, allowing you to use the value in subsequent rules.

  • ResultPropertyName - Required if ResultExpression is set. This is the property name under which the result of ResultExpression should be added to the rules evaluation context.

jsonSchema

Takes an optional JSON schema to validate the dataObject. This validation is done only once, applying only to the input parameter and not to any ResultExpression values added during rules evaluation. The JSON schema is an excellent way to ensure that all necessary input parameters for rules evaluation are provided and have the correct values.

Example

Let us do an example. We want to pass the total value of a purchase busket, along with a membership status and calculate a discount based on that:

  • Bronze status members receive 2%

  • Silver status members receive 5%

  • Gold status members receive 10%

Our dataObject parameter looks like this

{
  "totalValue": 7450.00,
  "memberStatus": "Silver"
}

The ruleDefinitions

Rule 1:

  • RuleName: IsBronze

  • EvaluationExpression: memberStatus == “Bronze”

  • ResultExpression: totalValue * 2 / 100

  • ResultPropertyName: discount

Rule 2:

  • RuleName: IsSilver

  • EvaluationExpression: memberStatus == “Silver”

  • ResultExpression: totalValue * 5 / 100

  • ResultPropertyName: discount

Rule 3:

  • RuleName: IsGold

  • EvaluationExpression: memberStatus == “Gold”

  • ResultExpression: totalValue * 10 / 100

  • ResultPropertyName: discount

These rules evaluate the value of memberStatus and calculate the discount.

Finally, we are adding a jsonSchema to ensure that memberStatus is either Bronze, Silver, or Gold, and that totalValue is greater than 0.

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "totalValue": {
      "type": "number",
      "exclusiveMinimum": 0
    },
    "memberStatus": {
      "type": "string",
      "enum": ["Bronze", "Silver", "Gold"]
    }
  },
  "required": ["totalValue", "memberStatus"],
  "additionalProperties": false
}

You can try it out in the demo application and the Last Evaluation Result should look like this

Change the values and add some extra rule expressions.

Result

After evaluation, the results are returned in the ValidationResult output parameter:

  • IsValid - This boolean value is true if all rules evaluated to true.

  • Document - Contains the rules evaluation context JSON document, including all added result properties.

  • RuleResults - An array of individual rule results. There is one entry for each rule evaluated, with the RuleName and a boolean IsValid property indicating whether the rule evaluated to true. You can use these individual entries to selectively take action within an action flow based on the result of a rule.

Summary

This article introduces the RulesEspresso external logic library for OutSystems Developer Cloud. RulesEspresso is a simple rules engine that lets you externalize business rules instead of hard-coding them into OutSystems applications. While it handles many use cases, for more complex scenarios, you might want to consider a Business Rules Management Solution. These solutions offer many extra features, including custom code integration and enterprise-level business rules evaluation, unlike RulesEspresso, which is designed for application-centric rules evaluation.

I hope you enjoyed it and would appreciate your feedback.

0
Subscribe to my newsletter

Read articles from Stefan Weber directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Stefan Weber
Stefan Weber

Throughout my diverse career, I've accumulated a wealth of experience in various capacities, both technically and personally. The constant desire to create innovative software solutions led me to the world of Low-Code and the OutSystems platform. I remain captivated by how closely OutSystems aligns with traditional software development, offering a seamless experience devoid of limitations. While my managerial responsibilities primarily revolve around leading and inspiring my teams, my passion for solution development with OutSystems remains unwavering. My personal focus extends to integrating our solutions with leading technologies such as Amazon Web Services, Microsoft 365, Azure, and more. In 2023, I earned recognition as an OutSystems Most Valuable Professional, one of only 80 worldwide, and concurrently became an AWS Community Builder.