{"id":15064342,"url":"https://github.com/sovanmukherjee/springboot-drools-decision-table","last_synced_at":"2026-01-05T17:10:16.135Z","repository":{"id":249444496,"uuid":"831497583","full_name":"sovanmukherjee/springboot-drools-decision-table","owner":"sovanmukherjee","description":"Drools Decision Tables example with Spring Boot ","archived":false,"fork":false,"pushed_at":"2024-07-26T17:26:09.000Z","size":89,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-01-30T12:22:05.764Z","etag":null,"topics":["decision-tables","drools","excel","gradle","java-21","spring-boot-3"],"latest_commit_sha":null,"homepage":"https://sovanmukherjee.github.io/springboot-drools-decision-table/","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/sovanmukherjee.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-07-20T18:16:53.000Z","updated_at":"2024-08-28T12:18:54.000Z","dependencies_parsed_at":"2024-07-23T20:15:43.085Z","dependency_job_id":null,"html_url":"https://github.com/sovanmukherjee/springboot-drools-decision-table","commit_stats":null,"previous_names":["sovanmukherjee/springboot-drools-decision-table"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sovanmukherjee%2Fspringboot-drools-decision-table","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sovanmukherjee%2Fspringboot-drools-decision-table/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sovanmukherjee%2Fspringboot-drools-decision-table/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sovanmukherjee%2Fspringboot-drools-decision-table/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sovanmukherjee","download_url":"https://codeload.github.com/sovanmukherjee/springboot-drools-decision-table/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245468920,"owners_count":20620489,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["decision-tables","drools","excel","gradle","java-21","spring-boot-3"],"created_at":"2024-09-25T00:15:50.426Z","updated_at":"2026-01-05T17:10:16.093Z","avatar_url":"https://github.com/sovanmukherjee.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Getting Started 🚀 \n\n## [✨ _Spring Boot 3 + Drools + Decision tables_ ✨](https://github.com/sovanmukherjee/springboot-drools-decision-table) \n\n\u003cimg width=\"123\" alt=\"springboot\" src=\"https://github.com/user-attachments/assets/8dd658a0-7630-4363-8975-f642c203860f\"\u003e    \u003cimg width=\"123\" alt=\"drools\" src=\"https://github.com/user-attachments/assets/9a232a90-0ef4-4400-98aa-c7632e6eafc8\"\u003e\n\n\n\n\n\n\n\n\n\n### Overview\nDrools is an open-source business rule management system (BRMS) that helps businesses automate decision-making by defining rules that determine what actions to take in various situations. Drools is a java-based rules engine that allows you to separate business logic from the application code, making it more easier to maintain, update and reuse.\n\n#### Drools Basics\nThere are several ways to define rules in Drools, making it flexible and accessible for different users from developers to business analysts. Here are the few primary methods:\n1. [Drools Rule Language (DRL):](https://docs.drools.org/8.39.0.Final/drools-docs/docs-website/drools/language-reference/index.html#:~:text=Using%20spreadsheet%20features-,Drools%20Rule%20Language%20(DRL),defining%20and%20describing%20business%20rules.) A native language for writing rules in Drools, similar to Java syntax.\n   \n    Structure: Rules are written in plain text files with a .drl extension.\n   \n    Example:\n    ```sh\n    package package-name\n    imports\n    globals\n    functions\n    queries\n    rule \"rule name\"\n    // Attributes\n    when\n        LHS // Conditions\n    then\n        RHS // Actions\n    end\n    rule \"rule2 name\"\n\n    ...\n    ```\n2. [Decision Tables:](https://docs.jboss.org/drools/release/5.2.0.Final/drools-expert-docs/html/ch06.html) Rules can be defined in spreadsheets, typically Excel.\n   \n   Advantages: Easier for non-technical users to manage rules in a tabular format. Each row represents a rule with columns for conditions and actions.\n   Example:  [discount.xls](https://github.com/sovanmukherjee/springboot-drools-decision-table/blob/main/src/main/resources/rules/discount.xls)\n\n3. [Domain-Specific Languages (DSLs)](https://docs.jboss.org/drools/release/5.3.0.Final/drools-expert-docs/html/ch05.html#d0e6317): Allows creation of a custom language tailored to specific business domains.\n\n   Structure: A DSL file with a .dsl extension is a text file in a line-oriented format. Its entries are used for transforming a DSLR file into a file according to DRL syntax.\n   Example:\n   ```\n   [when]There is a customer with age greater than {age}=Customer(age \u003e {age})\n   [then]Approve the customer's loan=approveLoan($customer)\n   ```\n   \u003cspan style=\"color: green\"\u003e In this example we have used Decision Tables by creating excel file spreadsheet inside the spring boot application. \u003c/span\u003e  \n\n##### Advantages of Using Decision Tables\n1. [Clarity and Readability:](https://github.com/sovanmukherjee/springboot-drools-decision-table/tree/main?tab=readme-ov-file#advantages-of-using-decision-tables) Presents rules in a clear, tabular format that is easy to read and understand.\n2. [Visualization:](https://github.com/sovanmukherjee/springboot-drools-decision-table/tree/main?tab=readme-ov-file#advantages-of-using-decision-tables) Provides a visual representation of rules making it easier to identify gaps or overlaps in logic.\n3. [Ease of Maintenance:](https://github.com/sovanmukherjee/springboot-drools-decision-table/tree/main?tab=readme-ov-file#advantages-of-using-decision-tables) Simplifies the process of updating rules as changes can be made directly in the table without delving into complex code.\n4. [Collaboration:](https://github.com/sovanmukherjee/springboot-drools-decision-table/tree/main?tab=readme-ov-file#advantages-of-using-decision-tables)  Facilitates collaboration between business analysts and developers as both can work from the same table format.\n5. [Efficiency:](https://github.com/sovanmukherjee/springboot-drools-decision-table/tree/main?tab=readme-ov-file#advantages-of-using-decision-tables) Reduces redundancy by consolidating multiple related rules into a single table.\n6. [Consistency:](https://github.com/sovanmukherjee/springboot-drools-decision-table/tree/main?tab=readme-ov-file#advantages-of-using-decision-tables) Ensures consistent application of rules as the table format reduces the likelihood of errors and omissions.\n\n##### When to Avoid Using Decision Tables\n1. [Non-Tabular Logic:](https://github.com/sovanmukherjee/springboot-drools-decision-table/tree/main?tab=readme-ov-file#when-to-avoid-using-decision-tables) When the rules do not fit into a tabular structure or involve complex logic that cannot be easily expressed in a table format. Decision tables are not suitable for rules that require intricate conditional logic or multiple interdependencies that are difficult to represent in rows and columns.\n2. [Small Number of Rules:](https://github.com/sovanmukherjee/springboot-drools-decision-table/tree/main?tab=readme-ov-file#when-to-avoid-using-decision-tables) When there are only a few rules to manage. The overhead of setting up and maintaining a decision table might not be justified for a small number of rules, which can be more easily managed directly in code or through simple rule definitions.\n3. [Unstructured Rules:](https://github.com/sovanmukherjee/springboot-drools-decision-table/tree/main?tab=readme-ov-file#when-to-avoid-using-decision-tables) Decision tables work best for rules that have a uniform structure. If the rules are too diverse or unstructured, it can be challenging to fit them into a decision table format.\n4. [Preference Against Spreadsheets:](https://github.com/sovanmukherjee/springboot-drools-decision-table/tree/main?tab=readme-ov-file#when-to-avoid-using-decision-tables) When there is a dislike or organizational policy against using spreadsheet software like Excel or OpenOffice.org.\n\n### Guides\nIn this example, we have defined the following rules using a decision table and the application will apply the highest possible discount on the purchase amount.\n\n1. If the total purchase amount is greater than or equal to 60,000 then a maximum highest discount rate 12% will be applied.\n  ![image](https://github.com/user-attachments/assets/c741a3dc-b3c0-4071-8728-0fddb8554aad)\n\n2. If the total purchase amount is greater than or equal to 40,000 then 6% discount(3rd highest discount rate) will be applied.\n  ![image](https://github.com/user-attachments/assets/2b5e2d51-babd-482d-9d62-54b380c17f77)\n\n\n3. If the total purchase amount is greater than or equal to 30,000 and if the user is from Arunachal Pradesh, Jammu and Kashmir, Lakshadweep, or Assam then a state-specific discount (2nd  highest discount rate ) will be applied.\n ![image](https://github.com/user-attachments/assets/6933cafa-9178-4757-9f49-92d9b3e3d276)\n\n#####   \u003cspan style=\"color: red\"\u003e Q1:  How can you stop rule execution once the first match is found in a decision table? \u003c/span\u003e\nApproach: You can add an extra ACTION column and have in it \"drools.halt();\". Then in the row, put some text (such as \"Y\" or TRUE or \"stop\", the specific text doesn't matter as long as there is something present)\n![image](https://github.com/user-attachments/assets/016daaea-634c-4d30-bbfd-fb05d406fb45)\n\n\n##### Technologies used in this example\n- Spring boot version: 3.3.1\n- Drools\n- Java version 21\n\nStep 1: Create a spring boot application and add required dependencies\n\n![image](https://github.com/user-attachments/assets/ed198c2e-fc08-4ce9-bf21-0c7ccc6e8351)\n\n\nStep 2: Creating the Excel spreadsheet drools decision table\n\n![image](https://github.com/user-attachments/assets/6e1bfeb9-87b2-4db4-90b4-0323fbe62389)\n\nDRL format of the above drools decision table:\n```sh\npackage rules;\n//generated from Decision Table\nimport org.drools.example.model.RuleDataset;\nimport java.math.BigDecimal;\nimport java.math.RoundingMode;\nfunction boolean hasTotalPurchaseAmountReachedThresholdAmount(BigDecimal totalPurchaseAmount, double thresholdAmount) {\n       return totalPurchaseAmount.compareTo(BigDecimal.valueOf(thresholdAmount)) \u003e=  0;\n    }\n\n function BigDecimal getPayableAmount( BigDecimal totalPurchaseAmount, int discountRate) {\n        return totalPurchaseAmount\n                .subtract(totalPurchaseAmount\n                        .multiply(BigDecimal.valueOf(discountRate))\n                                .divide(BigDecimal.valueOf(100),2, RoundingMode.UP));\n    }\n\n// rule values at A13, header at A8\nrule \"Total purchase amount  \u003e=  60000\"\n\tsalience 65535\n\twhen\n\t\truleDataset: RuleDataset(hasTotalPurchaseAmountReachedThresholdAmount(ruleDataset.getTotalPurchaseAmount(), 60000))\n\tthen\n\t\truleDataset.setDiscountAllowed(true) ;\n\t\truleDataset.setDiscountRate(12);\n\t\truleDataset.setPayableAmount(getPayableAmount(ruleDataset.getTotalPurchaseAmount(), ruleDataset.getDiscountRate()));\n\t\tdrools.halt();\nend\n\n// rule values at A20, header at A15\nrule \"Total purchase amount  \u003e=  30000 AND State code is JK\"\n\tsalience 65534\n\twhen\n\t\truleDataset: RuleDataset(hasTotalPurchaseAmountReachedThresholdAmount(ruleDataset.getTotalPurchaseAmount(), 30000), ruleDataset.getStateCode() == \"JK\")\n\tthen\n\t\truleDataset.setDiscountAllowed(true) ;\n\t\truleDataset.setDiscountRate(9);\n\t\truleDataset.setPayableAmount(getPayableAmount(ruleDataset.getTotalPurchaseAmount(), ruleDataset.getDiscountRate()));\n\t\tdrools.halt();\nend\n\n// rule values at A21, header at A15\nrule \"Total purchase amount  \u003e=  30000 AND State code LD\"\n\tsalience 65533\n\twhen\n\t\truleDataset: RuleDataset(hasTotalPurchaseAmountReachedThresholdAmount(ruleDataset.getTotalPurchaseAmount(), 30000), ruleDataset.getStateCode() == \"LD\")\n\tthen\n\t\truleDataset.setDiscountAllowed(true) ;\n\t\truleDataset.setDiscountRate(10);\n\t\truleDataset.setPayableAmount(getPayableAmount(ruleDataset.getTotalPurchaseAmount(), ruleDataset.getDiscountRate()));\n\t\tdrools.halt();\nend\n\n// rule values at A22, header at A15\nrule \"Total purchase amount  \u003e=  30000 AND State code is  AS\"\n\tsalience 65532\n\twhen\n\t\truleDataset: RuleDataset(hasTotalPurchaseAmountReachedThresholdAmount(ruleDataset.getTotalPurchaseAmount(), 30000), ruleDataset.getStateCode() == \"AS\")\n\tthen\n\t\truleDataset.setDiscountAllowed(true) ;\n\t\truleDataset.setDiscountRate(8);\n\t\truleDataset.setPayableAmount(getPayableAmount(ruleDataset.getTotalPurchaseAmount(), ruleDataset.getDiscountRate()));\n\t\tdrools.halt();\nend\n\n// rule values at A23, header at A15\nrule \"Total purchase amount  \u003e=  30000 AND State code are AR\"\n\tsalience 65531\n\twhen\n\t\truleDataset: RuleDataset(hasTotalPurchaseAmountReachedThresholdAmount(ruleDataset.getTotalPurchaseAmount(), 30000), ruleDataset.getStateCode() == \"AR\")\n\tthen\n\t\truleDataset.setDiscountAllowed(true) ;\n\t\truleDataset.setDiscountRate(10);\n\t\truleDataset.setPayableAmount(getPayableAmount(ruleDataset.getTotalPurchaseAmount(), ruleDataset.getDiscountRate()));\n\t\tdrools.halt();\nend\n\n// rule values at A30, header at A25\nrule \"Total purchase amount  \u003e=  40000\"\n\tsalience 65530\n\twhen\n\t\truleDataset: RuleDataset(hasTotalPurchaseAmountReachedThresholdAmount(ruleDataset.getTotalPurchaseAmount(), 40000))\n\tthen\n\t\truleDataset.setDiscountAllowed(true) ;\n\t\truleDataset.setDiscountRate(6);\n\t\truleDataset.setPayableAmount(getPayableAmount(ruleDataset.getTotalPurchaseAmount(), ruleDataset.getDiscountRate()));\n\t\tdrools.halt();\nend\n```\n\n\n\nStep 3: Add the drools configuration in spring boot application\n\n![image](https://github.com/user-attachments/assets/cd0b423d-65c6-4fd2-8c43-f5f09ee07d1b)\n\nWe configured 'StatelessKieSession' as a Spring bean to be used in the service layer.\n\nStep 4: Create a REST endpoint\n\n![image](https://github.com/user-attachments/assets/dc39ed86-d55c-41c0-ae40-ff94e4dc2e3f)\n\n\nStep 5: Add service layer\n\n![image](https://github.com/user-attachments/assets/68fb0e92-dfd2-4ea3-98fd-3c5227e08917)\n\n\nStep 6: Start the Spring Boot application and open the Swagger endpoint.\n![image](https://github.com/user-attachments/assets/45aa2b65-3cf4-426a-8b16-31daca3d0a04)\n\nhttp://localhost:8080/swagger-ui/index.html\n![image](https://github.com/user-attachments/assets/589444ae-85eb-4c80-9dc9-829fc02bb503)\n\n\nInput-1:\n![image](https://github.com/user-attachments/assets/3b793c1d-23b6-4004-9dd3-97154cb1ed46)\nOutput:\n![image](https://github.com/user-attachments/assets/e6996ed0-9eaf-440f-a615-65131d85d2cb)\n\n\nInput-2:\n![image](https://github.com/user-attachments/assets/e1c15e9d-c4ac-4890-a272-65c2a7d0462b)\nOutput:\n![image](https://github.com/user-attachments/assets/ff9372eb-e297-47cf-93b0-3499f8faf79a)\n\n\nInput-3:\n![image](https://github.com/user-attachments/assets/ac9e70ec-8fef-461b-8763-ee40a8d872c6)\nOutput:\n![image](https://github.com/user-attachments/assets/5393c9cd-fca8-4775-8ba7-dd897bc642f5)\n\n\nInput-4:\n![image](https://github.com/user-attachments/assets/c683fa47-03e0-4d7d-a57c-297372bf4511)\nOutput:\n![image](https://github.com/user-attachments/assets/6b091abe-55a8-4303-9e53-745f765902fe)\n\n### Reference Documentation\nFor further reference, please consider the following sections:\n\n* [Drools Expert User Guide](https://docs.drools.org/6.0.0.Beta2/drools-expert-docs/html_single/)\n* [The Rule Engine](https://docs.jboss.org/drools/release/5.2.0.Final/drools-expert-docs/html/ch01.html)\n* [Decision Tables](https://docs.jboss.org/drools/release/5.2.0.Final/drools-expert-docs/html/ch06.html)\n\n### Additional Links\nThese additional references should also help you:\n\n* [Gradle Build Scans – insights for your project's build](https://scans.gradle.com#gradle)\n* [Building a RESTful Web Service](https://spring.io/guides/gs/rest-service/)\n* [Serving Web Content with Spring MVC](https://spring.io/guides/gs/serving-web-content/)\n* [Building REST services with Spring](https://spring.io/guides/tutorials/rest/)\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsovanmukherjee%2Fspringboot-drools-decision-table","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsovanmukherjee%2Fspringboot-drools-decision-table","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsovanmukherjee%2Fspringboot-drools-decision-table/lists"}