0 purchases
drules
Drules #
Drules is a simple rule engine for Dart. It allows you to define rules in Json format and execute them against a given context. The rules are defined in a simple Json format and can be easily extended to support more complex rules.
Usage #
To use Drules in your Dart code, add it as a dependency in your project.
dart pub add drules
copied to clipboard
A simple usage example:
import 'package:drules/drules.dart';
void main() async {
var jsonRules =
[
'''
{
"name": "rule1",
"conditions": {
"operator": ">",
"operands": ["age", 18]
},
"actionInfo": {
"onSuccess": {
"operation": "print",
"parameters": ["You are an adult"]
}
}
}
''',
'''
{
"name": "rule2",
"conditions": {
"operator": "<",
"operands": ["age", 18]
},
"actionInfo": {
"onSuccess": {
"operation": "print",
"parameters": ["You are a child as your age is ${age}"]
}
}
}
'''
];
var ruleRepository = StringRuleRepository(jsonRules);
var ruleEngine = RuleEngine(ruleRepository);
var context = RuleContext();
context.addFact("age", 20);
await ruleEngine.run(context);
}
copied to clipboard
Features #
Simple rule definition in Json format
Support for basic conditions and actions
Easily extensible to support more complex rules
Support for asynchronous actions
Support for custom actions
Support for custom conditions
Rules #
A rule is defined in a simple Json format. A rule consists of the following fields:
id: The unique identifier of the rule. The id will be automatically generated if not provided.
name: The name of the rule. This is optional and can be used for debugging purposes.
priority: The priority of the rule. The rules are executed in the order of their priority. The default priority is 0.
enabled: A flag to indicate whether the rule is enabled or not. The default value is true.
conditions: The conditions that need to be satisfied for the rule to be executed. More details about conditions are provided below.
actionInfo: Information about the actions to be executed when the rule is activated. The actionInfo is defined in the following format:
onSuccess: The action to be executed when the rule is successful.
operation: The operation to be executed.
parameters: The parameters to be passed to the operation.
onFailure: The action to be executed when the rule execution fails due to an error.
operation: The operation to be executed.
parameters: The parameters to be passed to the operation.
Conditions #
A condition consists of the following fields:
operator: The operator to be used to evaluate the condition. It can be one of the following built-in operators or any user-defined operator:
==: Equal to
!=: Not equal to
>: Greater than
<: Less than
>=: Greater than or equal to
<=: Less than or equal to
!: Negation of the operand
all: All operands must be true
any: Any operand must be true
none: None of the operands must be true
contains: The first operand must contain the second operand
startsWith: The first operand must start with the second operand
endsWith: The first operand must end with the second operand
matches: The first operand must match the regular expression in the second operand
expression: The first operand must evaluate to true using the expression in the second operand
operands: A list of operands to be used in the evaluation.
Examples #
Simple condition
{
"operator": ">",
"operands": ["age", 18]
}
copied to clipboard
Complex condition
{
"operator": "all",
"operands": [
{
"operator": ">",
"operands": ["age", 18]
},
{
"operator": "<",
"operands": ["age", 60]
}
]
}
copied to clipboard
Expression condition
Drules supports expression conditions. The expression condition allows you to define a custom expression to evaluate the condition. It uses the template_expressions package to evaluate the expression.
If you want to use Dart objects in the expression, you have to pass the MemberAccessor object to the RuleContext object. The MemberAccessor object provides access to the fields/methods of the Dart objects in the expression.
// user defined object
class Counter {
int _value;
Counter(this._value);
void increment() {
_value++;
}
int get value => _value;
}
var context = RuleContext(resolve: [
MemberAccessor<Counter>({
'value': (c) => c.value,
'increment': (c) => c.increment,
}),
]);
context.addFact('counter', Counter(2));
copied to clipboard
The expression condition is defined in the following format:
{
"operator": "expression",
"operands": ["counter.value == 2"]
}
copied to clipboard
Custom condition
A custom condition can be defined by extending the Condition class. It must be registered with the RuleEngine object to be used in the rules.
ruleEngine.registerCondition(CustomCondition('isEven', (operands, context) {
return operands[0] % 2 == 0;
}));
copied to clipboard
Then it can be used in the rules as follows:
{
"operator": "isEven",
"operands": [2]
}
copied to clipboard
Actions #
An action consists of the following fields:
operation: The operation to be executed. The operation can be one of the following built-in operations or any user-defined operation:
print: Prints the output to the console.
expression: Evaluates a Dart expression.
stop: Stops further execution of the rule or other actions in the pipeline.
chain: All actions in the chain must be executed in the order they are defined.
parallel: All actions in the parallel block must be executed in parallel.
pipe: The output of one action is passed as input to the next action.
parameters: The parameters to be passed to the operation.
Examples #
Print action
{
"operation": "print",
"parameters": ["You are an adult"]
}
copied to clipboard
Expression action
Drules supports expression actions. The expression action allows you to define a custom expression to evaluate the action. It uses the template_expressions package to evaluate the expression.
Similar to the expression condition, you have to set the MemberAccessor object in the RuleContext object to use Dart objects in the expression.
{
"operation": "expression",
"parameters": ["counter.increment()"]
}
copied to clipboard
Custom action
A custom action can be defined by extending the Action class or by using the CustomAction class. It must be registered with the RuleEngine object to be used in the rules.
ruleEngine.registerAction(CustomAction('log', (parameters, context) {
print(parameters[0]);
}));
copied to clipboard
Then it can be used in the rules as follows:
{
"operation": "log",
"parameters": ["You are an adult"]
}
copied to clipboard
Rule Context #
The RuleContext object is used to store the facts and the MemberAccessor objects. The MemberAccessor object provides access to the fields/methods of the Dart objects in the expression.
var context = RuleContext(resolve: [
MemberAccessor<Counter>({
'value': (c) => c.value,
'increment': (c) => c.increment,
}),
], facts: {
'counter': Counter(2),
});
copied to clipboard
Rule Repository #
The RuleRepository object is used to store the rules.
StringRuleRepository #
The StringRuleRepository object is a simple implementation of the RuleRepository interface that stores the rules in a list of strings.
var jsonRules = [
'''
{
"name": "rule1",
"conditions": {
"operator": ">",
"operands": ["age", 18]
},
"actionInfo": {
"onSuccess": {
"operation": "print",
"parameters": ["You are an adult"]
}
}
}
'''
];
var ruleRepository = StringRuleRepository(jsonRules);
copied to clipboard
FileRuleRepository #
The FileRuleRepository object is an implementation of the RuleRepository interface that reads the rules from files or directory.
var ruleRepository = FileRuleRepository(
fileNames: [
'rules/rule_one.json',
'rules/rule_two.json',
],
);
copied to clipboard
Activation events #
Drules supports activation events. An activation event is a signal that triggers the execution of the rules. The activation event contains information about the rule that was activated, the facts that triggered the rule, and the result of the rule.
To listen to the activation events, you can add a listener to the RuleEngine object.
ruleEngine.addListener((event) {
print(event);
});
copied to clipboard
Or you can use (+) operator to add a listener.
ruleEngine + print;
copied to clipboard
Bugs and feature requests #
Please file feature requests and bugs at the issue tracker.
License #
Drules is released under the Apache License v2.
Support #
If you like this package and want to support our opensource work, consider sponsoring us via GitHub Sponsors.
Also consider supporting it by giving a star on GitHub and a like on pub.dev.
Contribution #
If you would like to contribute to this project, please feel free to send a pull request.
For personal and professional use. You cannot resell or redistribute these repositories in their original state.
There are no reviews.