json-schema-spec
json-schema-spec copied to clipboard
add section about keyword interaction mechanics being illustrative
Holding this PR based on the outcome of https://github.com/orgs/json-schema-org/discussions/491
Related to #1444
@jdesrosiers @Julian
Based on my ramblings here, what do you think of this (before I add it as a commit)?
Keyword Interactions
Keywords MAY modify their behavior based on the presence, absence, or value of another keyword in the same schema object. Such keywords MUST NOT result in a circular dependency.
Unless otherwise specified, keywords act independently.
Supplementary specifications are encouraged to specify any dependencies as part of the dependent keyword (i.e. the keyword whose behavior is modified).
Within this document, keyword dependencies are expressed using one of the following mechanics:
- Static dependencies, in which the dependency relies on the presence or contents of another keyword.
- Dynamic dependencies, in which the dependency relies on the evaluation of another keyword against an instance. This dependency may be on either the annotations produced by the keyword or the validation result of its subschema.
These mechanics are used merely to describe dependencies; they are for illustrative purposes and not prescriptive. Implementations MAY use whatever mechanisms makes sense given the needs of their architecture and language in order to achieve the specified behaviors.
~Annotations as an Interaction Mechanism~
That looks pretty good to me! Though the words "in the same schema object" at the beginning make me double take a bit (maybe those words were there before -- it seems so) -- unevaluatedProperties changes its behavior not just based on keywords in the same schema object but also whenever properties and friends appear potentially in subschema resources does it not?
But the rest certainly seems better than before to me, I have no suggestions for further improvements there. (Though I have to reread your other comment on the discussion)
unevaluatedProperties changes its behavior not just based on keywords in the same schema object but also whenever properties and friends appear potentially in subschema resources does it not?
I think it's argued that "subschemas" is included in "values."
If we like this, then I need to create a follow-up PR that removes annotation language from all of the static dependency keywords (that's gonna be a lot).
Also #1451 will need to be closed and those sections possibly re-evaluated. I'm not sure I like the way it's set up, and I think it could be improved. We'll see.
I think this is fantastic. I have one suggestion, but I'll save it for when you actually push the change. I'm 100% on board with the direction.
I think it would be good to also include a recommendation to strongly prefer static dependencies when designing keywords with interactions.
I'm iffy about this being in the spec. I think it would be good as (advanced) user guidance on the website.
This is a bit different from recommending that dependencies are defined as part of the dependent keyword, where the spec is more-or-less defining that one keyword can't actively modify other keyword's behavior; rather the second keyword modifies its own behavior based on the first.
I think it would be good to also include a recommendation to strongly prefer static dependencies when designing keywords with interactions.
I'm iffy about this being in the spec. I think it would be good as (advanced) user guidance on the website.
Well, I don't disagree with that, but I do think it's inconsistent with our recent decisions to include guidance in other places in the spec including this section.
This is a bit different from recommending that dependencies are defined as part of the dependent keyword, where the spec is more-or-less defining that one keyword can't actively modify other keyword's behavior; rather the second keyword modifies its own behavior based on the first.
I disagree. We established that the dependency directionality is a matter of perspective and the recommendation is merely an authoring style choice. Warning people off of dynamic keywords that are likely to be more difficult to implement and slower to evaluate than static keywords seems like more valuable guidance to include.
Warning people off of dynamic keywords that are likely to be more difficult to implement and slower to evaluate than static keywords seems like more valuable guidance to include.
I disagree. Warning people off dynamic keywords limits the keywords that people propose. Dynamic keywords aren't inherently more difficult to implement or slower to evaluate. They may be in your implementation (and perhaps others), but that's not universal.
Dynamic keywords aren't inherently more difficult to implement or slower to evaluate.
I disagree. I wasn't making a personal statement here. I believe that dynamic keywords are in general more difficult to implement and slower to evaluate. I certainly make unevaluated* harder due to my architectural choices, but I'm that's not what if talking about.
Dynamic keywords inherently require either maintaining state and managing order of evaluation or duplicating work. Both of those options carry complexity and performance costs. Implementing state management and managing order of operations adds complexity to your architecture and there is a performance cost associated with maintaining state that I've found to be significant. Duplicating validation can incur complexity in a different way and has a performance impact because evaluations are repeated. I acknowledge that it may be relatively easy to implement unevaluated* if you already have state management and order of evaluation as part of your architecture, but you still pay the cost of the added architectural complexity and performance to have those things.
From an anecdotal perspective, I think the current state of the ecosystem shows that implementers find dynamic dependencies more difficult to implement as they are the least likely to be implemented in implementations that claim partial support of 2019-09 and 2020-12 and more likely to be complained about by implementers trying to support the later versions. I would say the only thing in JSON Schema that gives implementers as much trouble as dynamic keywords is $id.
None of this is particularly relevant, but I wanted to respond to the accusation that my position is based on self-interest. The real issue here is whether or not we put guidance in the spec. Generally, I think no. I would hope that when we do, it's limited to times where we the guidance is universally agreed on. That's not the case here, but it's also not been the case for other guidance we recently decided should be in the spec, so it seems reasonable to consider if we're being consistent.
Build is running on an out of date JP spec. The main branch has been updated.