-
-
Notifications
You must be signed in to change notification settings - Fork 308
keywords only exhibit the behaviors they're defined with #1577
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 6 commits
de8ed30
2058d3e
a695c40
1a7a34a
50e9aca
b48cf71
78ca35d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -394,6 +394,18 @@ Additional schema keywords MAY be defined by any entity. Save for explicit | |||||||||||||||||
agreement, schema authors SHALL NOT expect these additional keywords to be | ||||||||||||||||||
supported by implementations that do not explicitly document such support. | ||||||||||||||||||
|
||||||||||||||||||
Extension keywords MUST NOT interfere with the operation of keywords defined by | ||||||||||||||||||
this document or the companion JSON Schema Validation specificiation, and SHOULD | ||||||||||||||||||
NOT interfere with the operation of keywords defined by other extension | ||||||||||||||||||
documents.[^11] | ||||||||||||||||||
|
||||||||||||||||||
[^11]: JSON Schema currently does not have a namespacing mechanism, which would | ||||||||||||||||||
allow multiple extensions to define the same keyword differently while also | ||||||||||||||||||
giving the schema author the ability to declare which definition is intended. | ||||||||||||||||||
Such a feature is planned for future releases. See the | ||||||||||||||||||
[Vocabularies / Extensions project](https://github.com/orgs/json-schema-org/projects/28/views/2) | ||||||||||||||||||
in GitHub for more information. | ||||||||||||||||||
|
||||||||||||||||||
Implementations MAY provide the ability to register or load handlers for | ||||||||||||||||||
keywords that they do not support directly. The exact mechanism for registering | ||||||||||||||||||
and implementing such handlers is implementation-dependent. | ||||||||||||||||||
|
@@ -415,20 +427,40 @@ keywords MUST NOT begin with this prefix. | |||||||||||||||||
Implementations MUST refuse to evaluate schemas which contain keywords which | ||||||||||||||||||
they do not know how to process or explicitly choose not to process. | ||||||||||||||||||
|
||||||||||||||||||
## Keyword Behaviors | ||||||||||||||||||
## Keyword Behaviors {#keyword-behaviors} | ||||||||||||||||||
|
||||||||||||||||||
JSON Schema keywords fall into several general behavior categories. Assertions | ||||||||||||||||||
validate that an instance satisfies constraints, producing a boolean result. | ||||||||||||||||||
Annotations attach information that applications may use in any way they see | ||||||||||||||||||
fit. Applicators apply subschemas to parts of the instance and combine their | ||||||||||||||||||
results. | ||||||||||||||||||
JSON Schema keywords may exhibit one or more behaviors. This specification | ||||||||||||||||||
defines three such behaviors[^7]: | ||||||||||||||||||
|
||||||||||||||||||
- Assertions validate that an instance satisfies constraints, producing a | ||||||||||||||||||
boolean result: `true` if the constraints are satisfied; `false` otherwise. | ||||||||||||||||||
- Annotations attach information to instance locations that applications may use | ||||||||||||||||||
in any way they see fit. | ||||||||||||||||||
- Applicators apply subschemas to parts of the instance and combine their | ||||||||||||||||||
results. | ||||||||||||||||||
|
||||||||||||||||||
[^7]: This specification also defines several operational directive keywords, | ||||||||||||||||||
such as `$id` and `$schema`, which do not exhibit these behaviors. Instead, | ||||||||||||||||||
these keywords provide metadata that instruct implementations on how to | ||||||||||||||||||
interpret and process the schema. | ||||||||||||||||||
|
||||||||||||||||||
Extension keywords SHOULD stay within these categories, keeping in mind that | ||||||||||||||||||
Extension keywords SHOULD be defined using these behaviors, keeping in mind that | ||||||||||||||||||
annotations in particular are extremely flexible. Complex behavior is usually | ||||||||||||||||||
better delegated to applications on the basis of annotation data than | ||||||||||||||||||
implemented directly as schema keywords. However, extension keywords MAY define | ||||||||||||||||||
other behaviors for specialized purposes. | ||||||||||||||||||
|
||||||||||||||||||
Implementations SHOULD NOT add unspecified behaviors to keywords. | ||||||||||||||||||
|
||||||||||||||||||
For the purposes of this document, an instance "validating against a keyword" | ||||||||||||||||||
means that the keyword produces an assertion result of `true` if the instance | ||||||||||||||||||
satisfies the given constraint; otherwise an assertion result of `false` is | ||||||||||||||||||
produced. | ||||||||||||||||||
|
||||||||||||||||||
<!-- The next two paragraphs and the following section seem to have more to | ||||||||||||||||||
do with schema evaluation than keywords specifically. I'd like to move them out | ||||||||||||||||||
of the "keyword behaviors" h2, but will do so separately. [TODO: GD] --> | ||||||||||||||||||
|
||||||||||||||||||
Evaluating an instance against a schema involves processing all of the keywords | ||||||||||||||||||
in the schema against the appropriate locations within the instance. Typically, | ||||||||||||||||||
applicator keywords are processed until a schema object with no applicators (and | ||||||||||||||||||
|
@@ -569,11 +601,17 @@ the keyword's value. Alternatively, an applicator may refer to a schema | |||||||||||||||||
elsewhere in the same schema document, or in a different one. The mechanism for | ||||||||||||||||||
identifying such referenced schemas is defined by the keyword. | ||||||||||||||||||
|
||||||||||||||||||
Applicator keywords also define how subschema or referenced schema boolean | ||||||||||||||||||
[assertion](#assertions) results are modified and/or combined to produce the | ||||||||||||||||||
boolean result of the applicator. Applicators may apply any boolean logic | ||||||||||||||||||
operation to the assertion results of subschemas, but MUST NOT introduce new | ||||||||||||||||||
assertion conditions of their own. | ||||||||||||||||||
Applicator keywords also behave as assertions by defining how subschema or | ||||||||||||||||||
referenced schema boolean [assertion](#assertions) results are modified and/or | ||||||||||||||||||
combined to produce the boolean result of the applicator. Applicators may apply | ||||||||||||||||||
Comment on lines
+604
to
+606
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm finding this sentence difficult to follow. I'm not sure what "referenced" means in this context. Also, I don't think it's necessary to say subschema "or" boolean schema because boolean schemas are subschemas. I'm also unsure what "modified" means in this context. What does it mean for an applicator to modify the result of a subschema? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 'referenced' seems okay to me; $ref has a referenced schema that isn't a subschema - although maybe that is better mentioned above in the initial description of applicator keyword behavior. The 'boolean' refers to an assertion result, not type of subschema, though the words/phrases run together a bit and it's difficult to parse how they are grouped (even knowing all the terms, much less while learning them).
Suggested change
Not quite polished - not suggesting that be put in as is, just thinking through what I might find to read better. (The spec is always very light on examples, I assume intentionally so maybe those don't go in, but I do always find they make the more generalized spec language much easier to connect to what it is describing). There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
(I wouldn't say the same thing before 2019-09. Back then I would call it something different than a schema.) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. sure, a schema containing a $ref isn't different than any other, but taking $ref as an applicator keyword, the schema it is doing application of is its referenced schema, not a subschema (I think I recall that your implementation does make it a subschema, but in the original document it isn't) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oh, I see what you mean. |
||||||||||||||||||
any boolean logic operation to the assertion results of subschemas, but SHOULD | ||||||||||||||||||
NOT introduce new assertion conditions of their own.[^2] | ||||||||||||||||||
|
||||||||||||||||||
[^2]: It is recommended that keywords have a single resposibility. An example of | ||||||||||||||||||
this in action is the separation between `properties`, which verifies object | ||||||||||||||||||
property values have the right data _if_ they exist, and `required`, which | ||||||||||||||||||
verifies that object properties exist. Separating these concerns allows for more | ||||||||||||||||||
reusable components. | ||||||||||||||||||
|
||||||||||||||||||
[Annotation](#annotations) results from subschemas are preserved in accordance | ||||||||||||||||||
with {{collect}} so that applications can decide how to interpret multiple | ||||||||||||||||||
|
@@ -1001,11 +1039,16 @@ identified schema. Its results are the results of the referenced schema.[^5] | |||||||||||||||||
[^5]: Note that this definition of how the results are determined means that | ||||||||||||||||||
other keywords can appear alongside of `$ref` in the same schema object. | ||||||||||||||||||
|
||||||||||||||||||
The value of the `$ref` keyword MUST be a string which is an IRI reference. | ||||||||||||||||||
gregsdennis marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||
The value of the `$ref` keyword MUST be a string which is an IRI reference. | ||||||||||||||||||
Resolved against the current IRI base, it produces the IRI of the schema to | ||||||||||||||||||
apply. This resolution is safe to perform on schema load, as the process of | ||||||||||||||||||
evaluating an instance cannot change how the reference resolves. | ||||||||||||||||||
|
||||||||||||||||||
The resolved IRI produced by `$ref` is not necessarily a network locator, only | ||||||||||||||||||
an identifier. A schema need not be downloadable from the address if it is a | ||||||||||||||||||
network-addressable URL. Implementations which can access the network SHOULD | ||||||||||||||||||
default to operating offline. | ||||||||||||||||||
gregsdennis marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||
The resolved IRI produced by `$ref` is not necessarily a network locator, only | ||||||||||||||||||
an identifier. A schema need not be downloadable from the address if it is a | ||||||||||||||||||
network-addressable URL. Implementations which can access the network SHOULD | ||||||||||||||||||
|
@@ -1476,8 +1519,8 @@ operators can contact the owner of a potentially misbehaving script. | |||||||||||||||||
|
||||||||||||||||||
## Keywords for Applying Subschemas | ||||||||||||||||||
|
||||||||||||||||||
This section defines a set of keywords that enable schema combinations and | ||||||||||||||||||
composition. | ||||||||||||||||||
This section defines a set of applicator keywords that enable schema | ||||||||||||||||||
combinations and composition. | ||||||||||||||||||
|
||||||||||||||||||
### Keywords for Applying Subschemas in Place {#in-place} | ||||||||||||||||||
|
||||||||||||||||||
|
@@ -1737,8 +1780,8 @@ The value of this keyword MUST be a non-negative integer. | |||||||||||||||||
This keyword modifies the behavior of `contains` within the same schema object, | ||||||||||||||||||
as described below in the section for that keyword. | ||||||||||||||||||
|
||||||||||||||||||
Validation MUST always succeed against this keyword. The value of this keyword | ||||||||||||||||||
is used as its annotation result. | ||||||||||||||||||
This keyword produces no assertion result. The value of this keyword is used as | ||||||||||||||||||
its annotation result. | ||||||||||||||||||
|
||||||||||||||||||
##### `minContains` | ||||||||||||||||||
|
||||||||||||||||||
|
@@ -1747,8 +1790,8 @@ The value of this keyword MUST be a non-negative integer. | |||||||||||||||||
This keyword modifies the behavior of `contains` within the same schema object, | ||||||||||||||||||
as described below in the section for that keyword. | ||||||||||||||||||
|
||||||||||||||||||
Validation MUST always succeed against this keyword. The value of this keyword | ||||||||||||||||||
is used as its annotation result. | ||||||||||||||||||
This keyword produces no assertion result. The value of this keyword is used as | ||||||||||||||||||
its annotation result. | ||||||||||||||||||
Comment on lines
+1788
to
+1789
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I prefer to stick with the "behavior" terminology for these things. What does it even mean to "produce an assertion result"? Is it a statement about output? (Those are rhetorical questions.) I think sticking to "behavior" terminology avoids that confusion. What matters is that the keyword has no affect on the validation result.
Suggested change
|
||||||||||||||||||
|
||||||||||||||||||
Per {{default-behaviors}}, omitted keywords MUST NOT produce annotation results. | ||||||||||||||||||
However, as described in {{contains}}, the absence of this keyword's annotation | ||||||||||||||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -62,6 +62,21 @@ information. The {{format}} keyword is intended primarily as an annotation, but | |
can optionally be used as an assertion. The {{content}} keywords are annotations | ||
for working with documents embedded as JSON strings. | ||
|
||
## Keyword Behaviors | ||
|
||
The keywords defined by this document exhibit one or more behaviors as defined by | ||
the [JSON Schema Core Specification](./jsonschema-core.md#keyword-behaviors). | ||
|
||
Keywords which are not defined to exhibit a particular behavior MUST NOT affect | ||
that aspect of the evaluation outcome. In particular, the keywords defined in | ||
{{annotations}} produce no assertion result and therefore are not considered | ||
during validation. | ||
|
||
For the purposes of this document, an instance "validating against a keyword" | ||
means that the keyword produces an assertion result of `true` if the instance | ||
satisfies the given constraint; otherwise an assertion result of `false` is | ||
produced. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This references Core Spec Keyword Behaviors but then also repeats, or is redundant with, a significant amount of that section. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The validation spec uses the phrase "an instance validates against this keyword if...", or some variant of it, quite a lot. I just wanted to define what that means. The phrasing is different than "this keyword exhibits assertion behavior by...", which feels more clunky to me (and I'd have to change a lot of places). |
||
|
||
## Interoperability Considerations | ||
|
||
### Validation of String Instances | ||
|
@@ -642,7 +657,7 @@ structures: first the header, and then the payload. Since the JWT media type | |
ensures that the JWT can be represented in a JSON string, there is no need for | ||
further encoding or decoding. | ||
|
||
## Keywords for Basic Meta-Data Annotations | ||
## Keywords for Basic Meta-Data Annotations {#annotations} | ||
|
||
These general-purpose annotation keywords provide commonly used information for | ||
documentation and user interface display purposes. They are not intended to form | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure what this is aiming to prevent.
Behaviors outside the three above? I'm not sure what that would be. That also seems more the concern of the definition of an extension keyword rather than an implementation.
Or behaviors within the three, but that aren't in a specification? If so, that seems just the nature of a specification, that an implementation of it sticks to its specified behaviors.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See, this thread.