Description
There are many applications where a schema is distributed for use by numerous, arbitrary validators. For example, an API describes to clients a range of values that are acceptable as input, or to describe exception cases that require special handling. In these applications, it’s important that all validators agree on the set of instances that a particular schema accepts and rejects. (It goes without saying by “validator” I mean “compliant validator.”)
However, JSON Schema has one quirk in particular that prevent this from being possible: Unknown keywords are treated if they didn’t exist. For a constraint-based system, this is a serious problem when a new keyword is introduced. If a schema author uses a newly standardized validation keyword, it’s likely for an important reason that should not be ignored—which is what older validators will do. While it should be possible to write keywords that are never ignored, this is not actually possible.
There’s two obvious ways to support this application; one is to introduce a scheme so that some properties in an object can be designated “must-understand” and require validators to implement this. The other is to report/handle keywords that are unknown, so the application can react appropriately.
The $vocabulary and $schema keywords offer partial solutions of the first class, but they are not complete. These keywords are a level of abstraction removed from the keywords the schema actually requires for correct processing; as a consequence, in the worst case, you can have two validators that cannot handle any schemas in common: you may have situations where two clients cannot be supported at the same time, even if their behavior is the same.
It seems that two schemas which have the same behavior, should also be supported by the same validators. So a general solution to this problem is likely to be a of the second class: Don’t require unknown keywords be ignored; but define some option to handle them unless they’re known to not be validation keywords (i.e. they are known to never reject an instance).
That is, the specification should describe how to identify those keywords that are unknown; and describe special cases where unknown keywords should not be ignored, but instead can be reported, raise an exception, or (if the details are unimportant) simply reject. Most validators can suffice with a runtime option: "Unknown keyword behavior: accept/error/reject". (The behavior currently required of implementations would be the "accept" option.)
I carefully word it this way so that, at least for now, there is no change in how schemas are processed (by default); rather this accommodates a class of applications that can enable stricter handling when that's what the application requires, and the impact of setting “error” as the default behavior can be better analyzed. (Though this can be decided now too, if some need presents itself.)
This is the first in a series of changes to implement JSON Schema Extensions, including:
- Standard way to indicate annotation-only keywords
- Refine definition of keywords, arguments, validation
- Typed “format” validation keywords
- Error handling keywords (to force rejection even by validators that ignore & accept unknown keywords)
It’s possible It may be preferable to implement some of these first, since that would lower the potential impact of this change.