06 — Rules
Building Rules (Functional)
Lambda rules are the quickest way to define rules in rulii. You write conditions and actions as Java lambdas, and the framework matches parameter names to bindings automatically.
Required Imports
import static org.rulii.model.condition.Conditions.condition;
import static org.rulii.model.action.Actions.action;
The Simplest Rule
Rule rule = Rule.builder()
.name("AlwaysTrue")
.given(condition(() -> true))
.then(action(() -> System.out.println("Fired!")))
.build();
Condition + Action with Parameters
Parameter names in the lambda must match binding names:
Rule rule = Rule.builder()
.name("AgeCheck")
.given(condition((Integer age) -> age >= 18))
.then(action(() -> System.out.println("Welcome!")))
.build();
rule.run(age -> 25); // Output: Welcome!
Multiple Then Actions
Rule rule = Rule.builder()
.name("MultiAction")
.given(condition((Integer score) -> score > 90))
.then(action(() -> System.out.println("Excellent!")))
.then(action((Binding<String> grade) -> grade.setValue("A")))
.build();
Otherwise (Else Branch)
Rule rule = Rule.builder()
.name("PassFail")
.given(condition((Integer score) -> score >= 60))
.then(action(() -> System.out.println("Pass")))
.otherwise(action(() -> System.out.println("Fail")))
.build();
rule.run(score -> 45); // Output: Fail
PreCondition (Skip Guard)
A pre-condition decides whether the rule should even attempt to run. If it returns false, the rule is skipped entirely:
Rule rule = Rule.builder()
.name("ConditionalRule")
.preCondition(condition((Boolean featureEnabled) -> featureEnabled))
.given(condition((Integer age) -> age >= 18))
.then(action(() -> System.out.println("Running!")))
.build();
// Pre-condition false → rule is SKIPPED (not FAIL)
rule.run(featureEnabled -> false, age -> 25);
Running Rules
// With lambda bindings
rule.run(name -> "Alice", age -> 30);
// With a Bindings object
Bindings b = Bindings.builder().standard();
b.bind("name", "Alice");
b.bind("age", 30);
rule.run(b);
// With a RuleContext
RuleContext ctx = RuleContext.builder().build(b);
RuleResult result = rule.run(ctx);
Complete Example: Date Validation
import static org.rulii.model.condition.Conditions.condition;
import static org.rulii.model.action.Actions.action;
Rule dateRule = Rule.builder()
.name("DateConsistency")
.given(condition((LocalDate startDate, LocalDate endDate)
-> startDate != null && endDate != null && !endDate.isBefore(startDate)))
.then(action(() -> System.out.println("Dates are valid")))
.otherwise(action(() -> System.out.println("End date must be after start date")))
.build();
dateRule.run(
startDate -> LocalDate.of(2025, 1, 1),
endDate -> LocalDate.of(2025, 12, 31)
);
// Output: Dates are valid
Warning
Due to the nature of how Lambdas are compiled in Java, generic parameter types and annotations are not persisted.
If you need those feaures you will have to define them manually. See example below:
Rule rule = Rule.builder()
.name("MyLambdaRule", "Rule demonstrating ParameterDefinitionEditor usage")
.given(
Condition.builder()
.with((List<String> value, Integer threshold) -> {
return value != null && value.size() > threshold;
})
// Override param 0: type
.param(0)
.type(new TypeReference<List<String>>() {})
.description("The input text value to validate")
.build()
// Override param 1: type, description, and default value
.param(1)
.description("The minimum length threshold")
.defaultValueText("3")
.build()
.build())
.build();