-
-
Notifications
You must be signed in to change notification settings - Fork 282
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
An alternate approach to meta-schemas #911
Comments
@jdesrosiers I think there are good ideas in here that would fit with the plan to have a machine-readable vocabulary file, which would handle things like "is this a validation assertion", "is this an in-place applicator", etc. #602 talks about this, but it's kind of a rambling mess and I should re-file it. This might not be as dramatic of a change, but might be a way to accomplish some of what you are talking about in way that fits a little more smoothly. Or by the time of the next draft (after this one), we might have more feedback on vocabularies etc. to justify a larger change. Thanks for filing this! |
I really like this. Nice job @jdesrosiers.
I don't think we need this (expanded upon below). When a meta-schema validates itself, it's not aware that this is what's going on. It's just validating an instance. It just so happens that the instance is the JSON representation of itself. @handrews in line with your ideas of machine-readable vocabs, the dereferenced schema would need to contain additional data about the keyword. The properties that define this metadata would only have meaning when dereferenced within the context of the {
"$keywordClass": "applicator",
... // more metadata
... // schema definition of the keyword
} Outside of the Lastly, just as with Also, @handrews, I appreciate your openness to this idea. I remember you had asked for other approaches before we published draft 2019-09, and the response was underwhelming. This, I think, counts toward that. |
@gregsdennis my intention would be to use the URI from Caveat: I have not delved into this issue deeply enough due to other distractions, just skimmed it, so this might not be right, I just wanted to get a general "yes there's stuff worth considering" comment on the record ASAP. |
I see where you're going with that, but I hesitate to reuse a keyword, even if it's relatively new and lightly adopted. This is quite a shift in design, even though the purpose is similar. I'd prefer to make the hard break and use |
@gregsdennis OK I'll have to put this on hold because I'm 800% overloaded right now, am farther behind on the current draft than I was a week ago, and seem to be missing something. But the explicit purpose of setting up We didn't create that semantic description file specifically in oder to see what people came back with after implementing, which @jdesrosiers has done. I might end up sold on the more dramatic reworking, but where I'd like to start is lining up this proposal with the (very vaguely articulated) original direction and seeing if that produces a good balance between disruption (keep in mind we're putting draft 2020-0? out with OAS 3.1/4.0 so unlike 2019-09 it will immediately have a huge user base) and functionality. |
That's a fair goal, but I think that this achieves the same end goals in a cleaner way. I imagine we'll continue to discuss. Join back in when you can. |
I agree that this could do that in the sense of not needing If y'all think we can/should dump But this feels to me more like a solution that overlaps rather than entirely replaces. |
That's true. Moving to keyword-level meta-schemas doesn't make
I definitely don't think that's a reasonable timeline. |
@gregsdennis {
"$meta": { "$href": "https://validation.hyperjump.io/common" },
"type": "object",
"patternProperties": {
"": { "validation": true }
}
} If I don't use |
2019-09 uses I guess that's the heart of the issue here. Maybe that can lead us to a more unified solution. [thinking out loud] If we break down the vocabularies further to their constituent keywords, we're pretty close to your idea with Each vocabulary meta-schema would merely be a collection of keyword meta-schemas, and they're all specified as required. Current implementation of applicator meta-schema
The idea here is that However, the meta-schema goes on to declare each keyword under I think these can be combined using the Thinking out loud model
This new document would also contain additional metadata about the keyword, whatever we need.
The key here is that tl;dr This uses the ideas from |
It's worth mentioning that one thing that |
@gregsdennis I've been really busy today and haven't had time to look at your last comment in detail, but I wanted to point this out ...
|
|
Regarding
Some of those very clearly map to either the behavior of the generic implementation or the behavior of the plugin. Others are not as clear and maybe are not necessary. One version of the idea allowed keywords to specify on which annotations they depended, and whether they depended on them from adjacent keywords only, or also from subschemas of adjacent in-place applicators. I decided that was probably complicating things. This is just a brain dump so y'all can pick over the ideas and see if any are helpful. |
Stepping back a bit, @awwright 's Philosophically, I think composition fits JSON Schema better than inheritance. |
Thanks for bringing the brain dump here, @handrews. That'll help. |
@gregsdennis I'm finally getting around to reviewing how you have applied It looks like you've kept the concept of a the vocabulary-level meta-schema, which is why the I don't see a way to declare the keyword name for a keyword in your example. Did you mean to use the keyword-name => keyword-id mapping like in Your example shows a vocabulary-level meta-schema, but I'm not sure what a dialect-level meta-schema would look like. |
Yeah, that's the idea. The dialect schema (I think this means "validates an individual keyword") is this bit
This validates the concept of the Then multiple vocabularies can be combined to achieve a full meta-schema. Finally the meta-schema is used to create schemas. |
@gregsdennis By dialect (@handrews's word) I mean the top level schema. Draft 2019-09 and OAS 3.1 are two examples of dialects. At the vocabulary-schema level, |
Ah... I see. It would work exactly as it does now: by pulling in multiple vocabularies. The hierarchy is
Each is represented by its own file, but the same format for all. You'd need the keyword metadata vocabulary to validate a schema because you need to validate keywords, but you shouldn't need it when validating an instance. With this setup, you could rename all of the keywords, and a validator should be completely fine with it because the keywords should be recognized by their NOTE This would require a fairly hefty rewrite of my library, so I don't propose it lightly. |
These seem like contradictory statements to me. How can If it uses keyword-name => keyword-id mapping, how do you do that on the dialect level where there are no keywords, just vocabularies? If it works as it does now, how are keyword names assigned to keyword-ids? An example of a meta-schema from each level (dialect, vocabulary, keyword) would probably be the best way to clear this up. |
I see what you mean. I'll work up a top-down example. |
This is the best I could come with. I had some other options, but they all lacked something or duplicated/muddled ideas.
This solution defines a new vocabulary: The other thing this does it make the vocab URIs deferenceable. The URI points to a resource that is itself a meta-schema that gathers keywords. An interesting side effect from this is that meta-schema authors can rename keywords. This is especially helpful when they want to reference two vocabularies with the same keyword but different meanings for them. As I stated before, an implementation wouldn't want to identify keywords based on the keyword name with this, which is what mine does (and probably most others). Instead it would need to use the ID for the keyword-meta-schema to identify whether it supports that keyword. |
Having only skimmed the issue, I'm keen to explore this... after draft-8-patch-1 |
@gregsdennis I like it. Allow me to iterate a bit. Meta-schemaNo changes here, but I'll point out that even tho the keywords are providing their own meta-schemas, additional constraints could be added here. For example, assume you want a standard JSON Schema, but you want to forbid the array form of {
"$schema": "https://json-schema.org/draft/2020-XX/schema",
"$id": "https://json-schema.org/draft/2020-XX/schema",
"$vocabulary": {
"https://json-schema.org/draft/2020-XX/vocab/applicator": true,
...
},
"$recursiveAnchor": true
} VocabularyThis one doesn't quite work. The {
"$schema": "https://json-schema.org/draft/2020-XX/vocabulary",
"$id": "https://json-schema.org/draft/2020-XX/vocab/applicator",
"$keywords": {
"multipleOf": "https://json-schema.org/draft/2020-XX/vocab/applicator/multipleOf",
"maximum": "https://json-schema.org/draft/2020-XX/vocab/applicator/maximum",
"properties": "https://json-schema.org/draft/2020-XX/vocab/applicator/properties",
...
}
} KeywordAgain, I don't think {
"$schema": "https://json-schema.org/draft/2020-XX/meta-schema",
"$id": "https://json-schema.org/draft/2020-XX/vocab/applicator/properties",
"type": "object",
"additionalProperties": { "$recursiveRef": "#" },
"default": {},
"$keywordClass": "applicator",
...
} The problem here is with the |
I think the idea I had going was that it was schema objects all the way down. That way we don't have to define a new document type. Additionally @handrews also conceived of defining a new document type for vocabs, but I rather like the idea of having the same document type describe all levels.
The reference goes back to the meta-schema root. I would say that if the target can't be found, the validator should fail (like if resolving |
I discovered this recently here (sorry, commit isn't as atomic as it should be) because of (possible) conflicts with Hope this is relevant/useful Sincerely |
Since there's been some discussion about
$recusriveAnchor
/$recursiveRef
lately, it might be a good time to share one of the experimental things I've tried out with Hyperjump Validation. It requires a big change to the concept of meta-schemas, but it eliminates the need for dynamic scope keywords and you basically get vocabulary support for free. It's not perfect and the syntax could certainly use some cleanup, but it has some pretty interesting properties.In Hyperjump Validation, instead of having a meta-schema that describes a schema, it uses a separate meta-schema for each keyword.
Here's how it works... Keywords are identified by URLs. Each keyword the schema can use is declared using the
$meta
keyword.$meta
works in a very similar way to@context
in JSON-LD mapping a plain name to a URL.The URL given to a keyword should be dereferenceable to a schema that validates that keyword. Therefore, a validator can determine if a keyword is valid even if it doesn't know how to evaluate the constraint that keyword expresses.
Declaring keywords this way is like in any programming language where you would import a
dependency before you use it. Any keyword that appears in the schema that is not declared in
$meta
is an error. Many people have wanted to include"additionalProperties": false
in the JSON Schema meta-schema. This constraint provides the protection people want from typos in keyword names without constraining extensibility.Most people wouldn't want to have to declare every keyword they use this way, so most schemas will likely choose to link to a common
$meta
that declares all the keywords they use. This list of keywords is effectively a vocabulary. This example uses the standard Hyperjump Validation vocabulary.A vocabulary can be constructed by creating a new
$meta
document that declares all the keywords for the vocabulary. This could include new keywords mixed with standard keywords or keywords from other vocabularies. When constructing a vocabulary, you can change the name of keywords (likedefinitions
to$defs
) just by changing the name of the keyword in the$meta
document. Another reason to change the name of something might be when combining two vocabularies that each have a keyword with the same name.That's all great, but we still need something like the old meta-schema so keyword meta-schemas that include schemas (like
properties
) can declare that something is a schema. To solve this problem, I created a new keyword calledvalidation
(orschema
in JSON Schema terms) that is a flag that indicates that the value should be a schema. It doesn't matter what vocabulary of the schema is. The schema will declare it's own vocabulary. This keyword only indicates that it's a schema of some kind.I don't imagine that anyone wants to make a change of this magnitude to JSON Schema, but hopefully it inspires people to look at the problem from a different angle and maybe come up with some new ideas that could be applied in a way that wouldn't completely change the way meta-schemas work.
The text was updated successfully, but these errors were encountered: