Go에서의 Rule Cascade
모듈: go get rulescascade.com/go (Go 1.26+, 표준 라이브러리 및 gopkg.in/yaml.v3 외에는 의존성 없음). 번들은 rcas compile --all로 생성되어 build/rules/에 위치합니다. 런타임에 YAML을 평가하거나 규칙을 코드에 복사하지 마십시오.
한 번 로드, 요청별 평가
import rulecascade "rulescascade.com/go"
// 시작 시. 오류가 있으면 시작하지 않음.
data, err := os.ReadFile("build/rules/<ruleset-id>.bundle.json")
doc, err := rulecascade.ParseJSON(data)
rules, err := rulecascade.FromBundle(doc)
미들웨어 사용을 권장합니다 (1.0.0-alpha.7부터): rulescascade.com/go/rulehttp는 JSON 본문(가독성 유지)에서 요청을 구성하고, 강제 적용하며, 거부된 요청에 대해 아래의 422 Problem Details로 응답합니다. 이는 모든 Rule Cascade 런타임에서 동일합니다.
mux.Handle("POST /orders", rulehttp.Enforce(rules, rulehttp.Options{Entity: "Order", Operation: "create",
Actor: func(r *http.Request) map[string]any { return actorFromToken(r) }})(createOrder))
// 핸들러 내부: rulehttp.FromContext(r.Context())는 허용된 결과입니다.
다른 곳에서는 rules.Enforce(request, "server", nil)이 *rulecascade.RuleViolation 오류를 반환하고(Problem()이 본문), rulehttp.WriteError(w, err)가 응답합니다. 내부적으로 rules.Evaluate(request, "server", nil)은 *rulecascade.Result를 반환합니다(Decision, Findings, Effects, Commands; result.Allowed()). *RuleSet은 동시 사용에 안전합니다. 모든 상태 변경 핸들러는 다음 네 단계를 따릅니다:
- 서버에서 평가
map[string]any{"entity", "operation", "data", "original", "actor", "resolutions"}사용. 액터는 인증 미들웨어에서 가져오며, 호출자가 제어하는 헤더에서 절대 가져오지 않습니다. 요청 본문은rulecascade.ParseJSON(또는json.Decoder.UseNumber())로 디코딩하여 숫자가 정확하게 유지되도록 합니다. - 거부 시 거절 422
application/problem+json(type: urn:rule-cascade:rule-violation) 결과를 포함하여 응답합니다. gRPC의 경우codes.FailedPrecondition과 findings를 details에 담습니다. - 지속화
compute효과(Type == "value")를 적용한 후: 서버의 값이 저장됩니다. result.Commands실행 커밋 후,IdempotencyKey당 한 번씩 실행합니다(아웃박스 테이블 또는 중복 제거가 있는 브로커).
배치: 엔티티당 하나의 함수가 요청을 구성하고 평가하며, 모든 핸들러(net/http, chi, gin, echo 모두 동일)에서 호출됩니다. rulecascade.NewHolder는 간격 또는 크론 스케줄에 따라 번들을 다시 로드하고 마지막으로 유효한 규칙을 유지합니다.
기존 검증 대체
rcas analyze --module <module>은 validate: 및 binding: 구조체 태그, ozzo-validation, 규칙 엔진, 수동 errors.New 검사, 명명된 제한(const MaxQuantity = 10), 숫자 비교 및 switch 분기를 나열합니다. drift가 있는 후보는 프로젝트의 다른 언어(주로 프론트엔드)가 동일한 이름을 다른 값으로 결정한다는 의미입니다. 하나의 규칙 집합이 둘 다 결정해야 합니다. 디코딩에서 형태 검사는 유지하고, 비즈니스 결정은 규칙으로 이동합니다. 기존 검사와 엔진에 대해 동일한 입력에 대한 테이블 기반 패리티 테스트를 추가한 후 기존 검사를 삭제합니다.
테스트
Decision 및 finding Code에 대한 테이블 기반 테스트(메시지 텍스트 제외). 규칙 집합의 골든 테스트(rcas check)는 규칙을 테스트합니다. CI는 go test 전에 rcas check 및 rcas compile --all을 실행합니다.