Targets
Say which entity a rule is about, and which field or fields its findings point at.
A rule's target says what the rule is about. entity names the data, and field or fields
names the JSON Pointers a finding points at. A form uses those pointers to show the message next to
the right input. The compiler checks every pointer against the entity's schema.
Syntax
target: { entity: Customer } # the whole entity
target: { entity: Customer, field: /email } # one field
target: { entity: Customer, fields: [/email, /backupEmail] } # several fieldsUse field or fields, never both.
Example
The second rule targets two fields, so its finding points at both.
ruleCascade: 1.0.0
kind: RuleSet
metadata: { id: learn.targets, version: 1.0.0, title: Targets }
scope:
- { level: organization, id: learn }
entities:
Customer:
schema: { $ref: "./learn.openapi.yaml#/components/schemas/Customer" }
rules:
- id: customer.email.required
kind: validation
target: { entity: Customer, field: /email }
operations: [create]
assert: { op: exists, args: [{ var: data.email }] }
severity: error
finding: { code: LRN-TGT-001, message: customer.emailMissing }
- id: customer.backup-email.different
kind: validation
target: { entity: Customer, fields: [/email, /backupEmail] }
operations: [create]
when: { op: exists, args: [{ var: data.backupEmail }] }
assert: { op: ne, args: [{ var: data.email }, { var: data.backupEmail }] }
severity: error
finding: { code: LRN-TGT-002, message: customer.sameEmails }
messages:
en:
customer.emailMissing: "Enter an e-mail address."
customer.sameEmails: "The backup e-mail must differ from the main e-mail."
tests:
- name: the same address twice is denied on both fields
entity: Customer
operation: create
given:
data: { email: ana@example.com, backupEmail: ana@example.com }
expect:
decision: deny
findings:
- { rule: customer.backup-email.different, fields: [/email, /backupEmail] }
- name: two different addresses are allowed
entity: Customer
operation: create
given:
data: { email: ana@example.com, backupEmail: ana@work.example }
expect: { decision: allow, findings: [] }{
"entity": "Customer",
"operation": "create",
"data": {
"email": "ana@example.com",
"backupEmail": "ana@example.com"
}
}Result, from the engine
Decisiondeny1 finding, server channel
LRN-TGT-002errorblockingThe backup e-mail must differ from the main e-mail./email, /backupEmail
Common mistakes
- A typo in a pointer. The compiler checks every path against the schema and refuses the ruleset
with
PATH_UNKNOWN:
ruleCascade: 1.0.0
kind: RuleSet
metadata: { id: learn.targets-fix, version: 1.0.0, title: "Targets, fix the path" }
scope:
- { level: organization, id: learn }
entities:
Customer:
schema: { $ref: "./learn.openapi.yaml#/components/schemas/Customer" }
rules:
- id: customer.email.required
kind: validation
target: { entity: Customer, field: /email }
operations: [create]
assert: { op: exists, args: [{ var: data.email }] }
severity: error
finding: { code: LRN-TGT-001, message: customer.emailMissing }
- id: customer.backup-email.different
kind: validation
target: { entity: Customer, fields: [/email, /backupEmial] }
operations: [create]
when: { op: exists, args: [{ var: data.backupEmail }] }
assert: { op: ne, args: [{ var: data.email }, { var: data.backupEmail }] }
severity: error
finding: { code: LRN-TGT-002, message: customer.sameEmails }
messages:
en:
customer.emailMissing: "Enter an e-mail address."
customer.sameEmails: "The backup e-mail must differ from the main e-mail."
tests:
- name: the same address twice is denied on both fields
entity: Customer
operation: create
given:
data: { email: ana@example.com, backupEmail: ana@example.com }
expect:
decision: deny
findings:
- { rule: customer.backup-email.different, fields: [/email, /backupEmail] }
- name: two different addresses are allowed
entity: Customer
operation: create
given:
data: { email: ana@example.com, backupEmail: ana@work.example }
expect: { decision: allow, findings: [] }{
"entity": "Customer",
"operation": "create",
"data": {
"email": "ana@example.com",
"backupEmail": "ana@example.com"
}
}Result, from the engine
does not loadThe engine refuses the ruleset before it evaluates anything.
PATH_UNKNOWNtarget /backupEmial is not in the Customer schema (line 19)
- Naming an entity that
entitiesdoes not declare. That isENTITY_UNKNOWN. - Writing a field as
emailordata.email. A target field is a JSON Pointer:/email.
Exercise
This ruleset does not load. Fix it so that it loads and its golden tests pass.
Hint
Read the problem: it names the path the schema does not have. Compare it with the field names in the schema.
Show answer
ruleCascade: 1.0.0
kind: RuleSet
metadata: { id: learn.targets-fix, version: 1.0.0, title: "Targets, fix the path" }
scope:
- { level: organization, id: learn }
entities:
Customer:
schema: { $ref: "./learn.openapi.yaml#/components/schemas/Customer" }
rules:
- id: customer.email.required
kind: validation
target: { entity: Customer, field: /email }
operations: [create]
assert: { op: exists, args: [{ var: data.email }] }
severity: error
finding: { code: LRN-TGT-001, message: customer.emailMissing }
- id: customer.backup-email.different
kind: validation
target: { entity: Customer, fields: [/email, /backupEmail] }
operations: [create]
when: { op: exists, args: [{ var: data.backupEmail }] }
assert: { op: ne, args: [{ var: data.email }, { var: data.backupEmail }] }
severity: error
finding: { code: LRN-TGT-002, message: customer.sameEmails }
messages:
en:
customer.emailMissing: "Enter an e-mail address."
customer.sameEmails: "The backup e-mail must differ from the main e-mail."
tests:
- name: the same address twice is denied on both fields
entity: Customer
operation: create
given:
data: { email: ana@example.com, backupEmail: ana@example.com }
expect:
decision: deny
findings:
- { rule: customer.backup-email.different, fields: [/email, /backupEmail] }
- name: two different addresses are allowed
entity: Customer
operation: create
given:
data: { email: ana@example.com, backupEmail: ana@work.example }
expect: { decision: allow, findings: [] }{
"entity": "Customer",
"operation": "create",
"data": {
"email": "ana@example.com",
"backupEmail": "ana@example.com"
}
}Result, from the engine
Decisiondeny1 finding, server channel
LRN-TGT-002errorblockingThe backup e-mail must differ from the main e-mail./email, /backupEmail