-
-
Notifications
You must be signed in to change notification settings - Fork 298
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
Add $vocabularies, clarify $schema and $ref #432
Conversation
$schema is now explicitly intended for meta-schema declaration. An explanation for why it MUST only be present in root schemas has been added so we (I) don't forget about it and freak out (again). The concept of vocabularies is now introduced explicitly, and the $vocabularies keyword is introduced to declare vocabulary support. For compatibility (and simplicity in the case of a single standard meta-schema conveying sufficient information), omitting $vocabularies in the root schema causes it to behave as if the $schema value is listed as a vocabulary. This preserves all existing behavior. Finally, a paragraph is added to $ref clarifying the conceptual model, specifically with respect to $schema and meta-schema validation.
This modifies the meta-schemas to explicitly forbid "$schema" in subschemas, and adds "$vocabularies".
Note the intended use of the meta-schemas includes both "$schema" and "$vocabularies".
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 believe $vocabulary should always be a single string, rather than array, so multiple vocabularies should not be allowed in the schemas. I also believe that $vocabulary should only be allowed in the root schema. I will elaborate in a separate comment.
The entire purpose of The nature of vocabularies is that they build on each other, so in order for a general system to tell whether their is a usable vocabulary, they need to know each vocabulary in the stack. You are essentially saying that you want |
@epoberezkin I could see an alternative where meta-schemas declare which vocabularies (plural) they describe. In this approach, implementations would examine the meta-schema to look for recognizable vocabularies, and instances would declare I would be just as happy with that approach. In both approaches, a conforming implementation that only wants to support validation with no extensions can almost entirely avoid |
@handrews, I definitely appreciate the progress, there are quite a few things in this PR we agree on. I will try to summarise what we agree on, please correct me if I am wrong:
Things we do not agree on (again, please correct me I am wrong):
Arguments to allow separate vocabularies in subschemas and allow multiple vocabularies
Arguments to NOT allow vocabularies in subschemas:
Arguments to NOT allow multiple vocabularies
So I may be missing something, but I really don't see how a questionable convenience of being able to package multiple schemas in a single file (particularly given that a simple alternative approach is possible - just define a package of schemas in the spec) can outweigh the above concerns. |
@handrew please hold on - writing more, answers to your questions :) |
I completely agree with that statement
Not necessarily, as the extended vocabulary knows which vocabulary it extends. hyper-schema extends validation. ui-schema may extend validation. Mixing ui-schema and hyper-schema - really? Do you have a use-case?
No, I don't say that. meta-schema can be extended. The whole purpose of using vocabulary is to define which library should be used.
That works for me too, as they are linked. Probably it is even better. But it means that the vocabulary cannot be changed in subschema. |
By the way, quite a few people asked how they can prohibit additional properties in the meta-schema. |
The only problem for that approach is that the meta-schema is a schema that should validate itself. So we could say, schema MAY include $vocabulary, but in this case it MUST have $schema and the $vocabulary in the schema should be the same as in the meta-schema. The meta-schema for any vocabulary would then look like this: {
"$schema": "some_uri",
"$vocabulary": "whatever",
"type": ["object", "boolean"],
"properties": {
"$schema": {"type": "string", "format": "uri"},
"$vocabulary": {"const": "whatever"},
"etc.": {}
},
"dependencies": {
"$vocabulary": ["$schema"],
"etc.": []
}
} Or maybe it's fine to have $vocabulary without $schema as well, we can say that both $schema implies $vocabulary and vice versa, and both MAY be used too but if so they MUST match (in which case "dependencies" above won't be needed). Ok, now I am done writing... |
One more thought. I actually agree that in the future we may need to be able to mix multiple vocabularies that can be used both separately and together. I hope that by then we will have a mechanism that allows to define a separate meta-schema by mixing individual meta-schemas. When (and if) we find ourselves in such predicament, nothing would stop us to allow a $vocabulary to be an array of strings as well. I just don't think we are there now and we may never get there, as at the moment we only have two standardised vocabularies: "validation" and "hyper-schema", the latter already inherits from "validation", it cannot be used WITHOUT it. Once we have mixable vocabularies together with meta-schema extension mechanism I would be very happy to support $vocabulary as array. At the moment we have neither. So why don't we keep things simple for now? |
@epoberezkin yeah, I think we can sort this out :-) As you observed from the proposal to move Pushing the conflicting bits out into separate files and
I'm not worried about an extended implementation knowing its base. It has to (if only to delegate it to another library). What I need is for a base implementation to understand an extended vocabulary. If I have a "handrews-hyper-schema" vocabulary, what I need is for my implementation to be able to recognize my own private extensions. However, I MUST NOT expect peer implementations to support them. What I need, then, is the principle of graceful degradation: If the standard hyper-schema vocabulary is explicitly declared (in the schema or meta-schema), then a standard hyper-schema library can make use of my extended schemas. I cannot think of any way to provide this without explicitly listing all of the schemas. We can explicitly list them in some form other than a flat list, but that is by far the easiest to handle. applications don't always validate or even have a copy of the meta-schema, and may not even be able to download one.
Um... yes. HATEOAS-driven UI. It's one of the primary use cases I have for hyper-schema. If there is no standard UI vocabulary, I'll do it with a custom one.
I am only willing to accept this as a reason if you have a workable proposal now. I have not heard anything. So I have a solution to this problem and you don't. Why should I throw away my solution for your vaporware that may or may not ever materialize?
No, you only see those. We also have three proposals, at least one of which has a de-facto implementation (json-schema-form). You also have no idea what I might be planning to do with schema vocabularies that I'm not proposing a standard vocabulary for (because not all vocabularies need to be standard). With all this in mind, I prefer that |
All you problems can be either solved with vocabulary extension (in which case you don't need multiple vocabularies) or with allOf, where different subschemas can be references to other files. I am well aware about the progress of other vocabularies, but none of them is a published draft at this point, so adding features to the core to support them without having them published is premature. You are ignoring the main question - how the meta-schema combining multiple vocabularies should be constructed. Once we agree on $merge or any other option from your vote-a-rama this problem will be solved. I see absolutely no problem with you using multiple vocabularies even if only one is specified in the spec - there are many people using $data, for example, without any problem. I keep saying that the usage practice should precede the spec. So at this point we really only need $vocabulary, singular. Later we can allow $vocabulary to be plural by allowing an array of strings (same as with "type"). The argument "I need it, you have no idea what I might be planning to do with schema vocabularies, and therefore it should be added to the spec" is neither proper nor convincing. Firstly, these plans should be explained and discussed to a wider community. Secondly, I would like to see substantially more support for mixing multiple vocabularies at this point, before we have more than 2 vocabularies standardised, when the second is the extension of the first (so no mixing is needed). To summarise, I am categorically against supporting mixing schema vocabulary at this point of JSON schema evolution - there is no proven need for it. |
@epoberezkin I am going to talk with the other active project members before continuing. |
I'm also just going to close this for now. I don't think the conversation is productive for others to read at this point, and I want people to focus on the hyperschema rewrite. |
This addresses issues #314 and #431.
"$schema"
is now explicitly intended for meta-schema declaration.An explanation for why it MUST only be present in root schemas
has been added so we (I) don't forget about it and freak out (again).
The concept of vocabularies is now introduced explicitly, and
the
"$vocabularies"
keyword is introduced to declare vocabularysupport. For compatibility (and simplicity in the case of
a single standard meta-schema conveying sufficient information),
omitting
"$vocabularies"
in the root schema causes it to behaveas if the
"$schema"
value is listed as a vocabulary. This preservesall existing behavior.
Finally, a paragraph is added to
"$ref"
clarifying the conceptualmodel, specifically with respect to
"$schema"
and meta-schemavalidation.