在 JVM 上使用 Rule Cascade
相依性(Maven):com.rulescascade:rules-cascade-core(Java 17+,無其他執行期相依性;套件 com.rulescascade)。Gradle:implementation("com.rulescascade:rules-cascade-core:<version>")。
Bundle 來自 rcas compile --all 並輸出至 build/rules/。切勿在執行期評估 YAML,也絕對不要將規則複製到程式碼中。
載入一次,每個請求評估一次
import com.rulescascade.*;
// 一個 Bean / Singleton,在啟動時建立。此處的例外必須中止應用程式。
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)。 行為者來自安全上下文,絕對不能來自呼叫者控制的請求頭。 - 拒絕時拒絕:當
!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 會依間隔或 cron 排程重新載入 bundle,並保留最後一組正確的規則。
取代現有驗證
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/