Implement Dynamic Discount Rules in Spring Boot with Drools
This guide shows how to integrate the Drools rule engine into a Spring Boot application to calculate e‑commerce discounts dynamically, covering Maven dependencies, configuration, model definitions, DRL rule creation, service and controller layers, and a simple test scenario demonstrating rule‑driven discount computation.
Introduction
When an e‑commerce system needs to calculate discounts based on flexible business rules—such as extra 5 % for VIP customers or an additional 10 % for orders over 1000 CNY—hard‑coding the logic would require code changes, retesting and redeployment each time a rule changes. Using a rule engine like Drools allows the rules to be externalised and modified without touching the business code.
Adding Maven Dependencies
Create a Spring Boot project and add the following Drools dependencies to pom.xml:
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-core</artifactId>
<version>7.59.0.Final</version>
</dependency>
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-compiler</artifactId>
<version>7.59.0.Final</version>
</dependency>
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-decisiontables</artifactId>
<version>7.59.0.Final</version>
</dependency>Drools Configuration Class
Create a DroolsConfig class that registers a KieContainer bean and loads the DRL files from src/main/resources/rules:
@Configuration
public class DroolsConfig {
// Path to the rule file
private static final String RULES_CUSTOMER_RULES_DRL = "rules/customer-discount.drl";
private static final KieServices kieServices = KieServices.Factory.get();
@Bean
public KieContainer kieContainer() {
KieFileSystem kieFileSystem = kieServices.newKieFileSystem();
kieFileSystem.write(ResourceFactory.newClassPathResource(RULES_CUSTOMER_RULES_DRL));
KieBuilder kb = kieServices.newKieBuilder(kieFileSystem);
kb.buildAll();
KieModule kieModule = kb.getKieModule();
return kieServices.newKieContainer(kieModule.getReleaseId());
}
}Defines a Spring bean of type KieContainer that loads the DRL file from the classpath.
Creates a KieFileSystem to write the rule file.
Builds the Drools module with KieBuilder.
Exposes the container as a Spring bean.
Business Model Classes
Define the request object, an enum for customer type, and a DTO for the discount result.
@Getter @Setter
public class OrderRequest {
private String customerNumber;
private Integer age;
private Integer amount;
private CustomerType customerType;
} public enum CustomerType {
LOYAL, NEW, DISSATISFIED;
public String getValue() { return this.toString(); }
} @Getter @Setter
public class OrderDiscount {
private Integer discount = 0;
}Drools Rules (customer-discount.drl)
The DRL file contains four rules that adjust a global orderDiscount object.
import com.alvin.drools.model.OrderRequest;
import com.alvin.drools.model.CustomerType;
global com.alvin.drools.model.OrderDiscount orderDiscount;
dialect "mvel"
// Rule 1: Age based discount
rule "Age based discount"
when
OrderRequest(age < 20 || age > 50)
then
System.out.println("==========Adding 10% discount for Kids/ senior customer=============");
orderDiscount.setDiscount(orderDiscount.getDiscount() + 10);
end
// Rule 2: Loyal customer discount
rule "Customer type based discount - Loyal customer"
when
OrderRequest(customerType.getValue == "LOYAL")
then
System.out.println("==========Adding 5% discount for LOYAL customer=============");
orderDiscount.setDiscount(orderDiscount.getDiscount() + 5);
end
// Rule 3: Other customer types
rule "Customer type based discount - others"
when
OrderRequest(customerType.getValue != "LOYAL")
then
System.out.println("==========Adding 3% discount for NEW or DISSATISFIED customer=============");
orderDiscount.setDiscount(orderDiscount.getDiscount() + 3);
end
// Rule 4: Amount based discount
rule "Amount based discount"
when
OrderRequest(amount > 1000L)
then
System.out.println("==========Adding 5% discount for amount more than 1000$=============");
orderDiscount.setDiscount(orderDiscount.getDiscount() + 5);
endService Layer
The OrderDiscountService obtains a KieSession, injects the global discount object, inserts the request, fires all rules and returns the calculated discount.
@Service
public class OrderDiscountService {
@Autowired
private KieContainer kieContainer;
public OrderDiscount getDiscount(OrderRequest orderRequest) {
OrderDiscount orderDiscount = new OrderDiscount();
KieSession kieSession = kieContainer.newKieSession();
kieSession.setGlobal("orderDiscount", orderDiscount);
kieSession.insert(orderRequest);
kieSession.fireAllRules();
kieSession.dispose();
return orderDiscount;
}
}Controller
Expose a REST endpoint that receives an OrderRequest JSON and returns the calculated OrderDiscount.
@RestController
public class OrderDiscountController {
@Autowired
private OrderDiscountService orderDiscountService;
@PostMapping("/get-discount")
public ResponseEntity<OrderDiscount> getDiscount(@RequestBody OrderRequest orderRequest) {
OrderDiscount discount = orderDiscountService.getDiscount(orderRequest);
return new ResponseEntity<>(discount, HttpStatus.OK);
}
}Testing
Run the Spring Boot application and POST a JSON payload such as:
{
"customerNumber": "C001",
"age": 18,
"amount": 1200,
"customerType": "LOYAL"
}For a loyal customer younger than 20 with an order amount greater than 1000, the rules above produce a total discount of 20 % (10 % age discount + 5 % loyal‑customer discount + 5 % amount discount).
Conclusion
By integrating Drools with Spring Boot we can externalise discount logic into a DRL file, allowing business users or product managers to add or modify rules—such as a new rule for customers in a specific city—without changing Java code, thus speeding up iteration and reducing deployment risk.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
macrozheng
Dedicated to Java tech sharing and dissecting top open-source projects. Topics include Spring Boot, Spring Cloud, Docker, Kubernetes and more. Author’s GitHub project “mall” has 50K+ stars.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
