--- layout: docs title: Defining rules header: Defining rules prev_section: user-guide/introduction next_section: user-guide/rules-engine doc: true --- The key API in Easy Rules is the `Rule` interface: ```java public interface Rule { /** * This method encapsulates the rule's conditions. * @return true if the rule should be applied, false else */ boolean evaluate(); /** * This method encapsulates the rule's actions. * @throws Exception thrown if an exception occurs * during actions performing */ void execute() throws Exception; //Getters and setters for rule name, //description and priority omitted. } ``` The `evaluate` method encapsulates conditions that must evaluate to _TRUE_ to trigger the rule. The `execute` method encapsulates actions that should be performed when rule's conditions are satisfied. You can define rules in two ways: * By implementing the `Rule` interface or extending the `BasicRule` class * Adding annotations on a POJO ## Defining rules by extending _BasicRule_ Easy Rules provides a simple implementation of the `Rule` interface named `BasicRule`. This class implements most of methods defined in the `Rule` interface. You can extends this class and override `evaluate` and `execute` methods to provide your conditions and actions logic. Here is an example: ```java public class MyRule extends BasicRule { private BusinessData myBusinessData; //data to operate on @Override public boolean evaluate() { //my rule conditions return true; } @Override public void execute() throws Exception { //my actions } } ``` ## Defining rules using annotations Easy Rules provides the `@Rule` annotation that can turn a POJO into a rule. Here is an example: ```java @Rule(name = "my rule", description = "my rule description") public class MyRule { private BusinessData myBusinessData; //data to operate on @Condition public boolean when() { //my rule conditions return true; } @Action(order = 1) public void then() throws Exception { //my actions } @Action(order = 2) public void finally() throws Exception { //my final actions } } ``` The `@Condition` annotation marks the method to execute to evaluate the rule conditions. This method must be public, have no parameters and return a boolean type. Only one method can be annotated with `@Condition` annotation. The `@Action` annotation marks methods to execute to perform rule actions. Rules can have multiple actions.
Actions can be executed in a specified order

You can also define the execution order of actions with the order attribute: @Action(order = 1). By default, the order of an action is 0.

## Composite rules Easy Rules allows you to create complex rules from primitive ones. A `CompositeRule` is composed of a set of rules. This is typically an implementation of the composite design pattern. A composite rule is triggered if **_all_** conditions of its composing rules are satisfied. When a composite rule is applied, actions of **_all_** composing rules are performed in the natural order of rules which is rules priorities by default. To create a composite rule from two primitive rules, you can use the following snippet: ```java //Create a composite rule from two primitive rules CompositeRule myCompositeRule = new CompositeRule("myCompositeRule", "a composite rule"); myCompositeRule.addRule(myRule1); myCompositeRule.addRule(myRule2); //Register the composite rule as a regular rule RulesEngine rulesEngine = aNewRulesEngine().build(); rulesEngine.registerRule(myCompositeRule); ``` ## Rules priorities Each rule in Easy Rules has a priority. This represents the default order in which registered rules are fired. By default, lower values represent higher priorities. To override this behavior, you should override the `compareTo` method to provide a custom priority strategy. * If you decided to extend the `BasicRule` class, you can specify rule priority at construction time or by overriding the `getPriority()` method * If your rule is a annotated POJO, you should annotate the method that provides priority with `@Priority` annotation. This method must be public, have no arguments and return an Integer type ## Rule listener You can listen to rule execution events through the `RuleListener` API: ```java public interface RuleListener { /** * Triggered before a rule is executed. */ void beforeExecute(Rule rule); /** * Triggered after a rule is executed successfully. */ void onSuccess(Rule rule); /** * Triggered after a rule is executed with error. */ void onFailure(Rule rule, Exception exception); } ``` You can implement this interface to provide custom behavior to execute before/after each rule. To register your listener, use the following snippet: ```java RulesEngine rulesEngine = aNewRulesEngine() .withRuleListener(myRuleListener) .build(); ``` You can register as many listeners as you want, they will be executed in their registration order.