JVM 上的 Rule Cascade 依赖(Maven):com.rulescascade:rules-cascade-core(Java 17+,无其他运行时依赖;包名 com.rulescascade)。Gradle:implementation("com.rulescascade:rules-cascade-core:<version>")。规则包通过 rcas compile --all 生成,输出到 build/rules/ 目录。切勿在运行时评估 YAML,也不必将规则复制到代码中。
一次加载,每次请求评估
import com.rulescascade.*;
// 一个 bean / 单例,在启动时创建。此处异常必须阻止应用启动。
RuleSet rules = RuleSet.fromBundle((Map<String, Object>) Json.parse(Files.readString(Path.of("build/rules/<ruleset-id>.bundle.json"))));
List<String> missing = rules.missingOperators(); // 规则所需的自定义运算符
if (!missing.isEmpty()) throw new IllegalStateException("未注册的运算符:" + missing);
当服务使用 Jackson 解析 JSON 时,启用 DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS,以便金额能够精确到达引擎。
推荐使用 rules.enforce(request)(自 1.0.0-alpha.7 起):它返回允许的结果或抛出 com.rulescascade.RuleViolationException,其 problem() 方法返回 422 响应,在所有 Rule Cascade 运行时中保持一致。一个全局处理器即可处理所有端点的异常:
@RestControllerAdvice
class RuleErrors {
@ExceptionHandler(RuleViolationException.class)
ResponseEntity<Map<String, Object>> denied(RuleViolationException e) {
return ResponseEntity.status(e.status()).contentType(MediaType.APPLICATION_PROBLEM_JSON).body(e.problem());
}
}
要使用注解作用于控制器方法,请从 Spring Boot 示例(https://rulescascade.com/reference/examples/backend-spring-boot/)复制 @EnforceRules 和 RuleEnforcementAspect;它需要 spring-boot-starter-aspectj(Spring Boot 4 之前为 spring-boot-starter-aop)。每个状态变更的端点遵循以下四个步骤:
- 在服务器端评估:
rules.evaluate(EvaluationRequest.builder(entity, operation).data(data).original(original).actor(...).build(), Channel.SERVER)。 actor 必须来自安全上下文,绝不能来自调用方控制的 Header。 - 拒绝时拒绝:当
!result.allowed()时,抛出RuleViolationException(result)并统一映射,在@RestControllerAdvice/ 异常映射器中,映射为 422ProblemDetail,其type: urn:rule-cascade:rule-violation,并将结果(result.toMap())作为属性包含在内。 - 持久化,在应用
compute效果后(effect.type()为value):存储服务器端值。 - 执行
result.commands(),在提交后(@TransactionalEventListener(phase = AFTER_COMMIT)或 outbox 模式),每个idempotencyKey执行一次。
位置:Spring 中提供一个 @Configuration 类,其中包含 RuleSet 的 @Bean 和每个实体用于构建请求的服务;Quarkus/Micronaut 中提供一个 @Singleton 生产者。Kotlin 和 Scala 调用相同的 API。RuleSetHolder 可按照时间间隔或定时计划重新加载规则包,并保留最后有效的规则。
替换现有验证
rcas analyze --module <module> 会列出 Bean Validation 注解、Spring 验证器和 @PreAuthorize、Drools .drl 规则、手动编写的检查、命名限制(MAX_QUANTITY = 10)、数字比较以及基于状态的 switch 分支。带有 drift 的候选项表示前端中同一名称存在其他值:必须由一个规则集同时决定两者。如果愿意,可以保留 DTO 上的 @NotNull/@Size 类型检查;将业务决策迁移到规则中。添加一个一致性测试(JUnit @ParameterizedTest,对旧检查和引擎使用相同的输入),然后删除旧检查。
测试
断言 decision 和查找代码,而不是消息文本。规则集中的黄金测试(rcas check)对规则进行测试;CI 在 mvn verify / gradle test 之前运行 rcas check 和 rcas compile --all。
参考:https://rulescascade.com/usage/java/ 和 https://rulescascade.com/playbooks/backend-api/