-
-
Notifications
You must be signed in to change notification settings - Fork 268
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
Should $ref be outside json-schema spec and just be a simple generic referencing mechanism? #279
Comments
There are a number of other related issues where a merge or patch or some sort of merging is suggested. They have had some discussion. As such I'm closing this issue in favour of the others that already exist, as I consider it a duplicate. (#15) |
This issue is not about merge and "schema extensions" has the issues you referred end up discussing. I just think the whole #use is case over annotation override is over complicated and harder to read. Are the "no additional props" in $ref that sacred? Also I agree that $merge should be outside the scope of json-schema spec. I'm having a hard time understanding that "allOf is nonsensical when combining multiple schemas using default"
A also disagree with "$merge'd document should be considered a new document, and get its own URI." Regarding $ref resolution and $id I think it's reasonable that a generic json $ref to have some king of mechanism to change base url based on some property value. In this case $id. Also I believe that $ref should be only about "inclusion" and really don't understand the problem with circular references and why $ref in this comment won't resolve. The only problem with circular references is when serializing. Otherwise validators should work on fully dereferenced objects where all reference are instanced. I think $ref and $merge should be out of scope of json-schema and validation which simplifies things a lot. Again sorry if I'm missing something obvious but sometimes I feel like the spec is getting a little heavy |
@ruifortes you're covering a huge span of topics here- I will try to pick this apart and answer the main concerns, but smaller, focused issues will make for easier discussion.
Your other comments seem to be mostly just comments, so I'll stop here. The |
@ruifortes You mean you don't understand why inclusion won't work or why recursion is needed?
Because it needs the base URI for it's resolution and it is outside of "included" fragment. After our "ad-nauseum" discussions :) I think we've all agreed two things (@handrews, correct me if I am wrong):
|
Well...I might have mixed up topics from my last post #278 and topics the posts you suggested end up discussion. I'll try to be more precise. Generally I think referencing, merging of patching should be outside json-schema scope. Regarding $use vs metadata props in $ref I would just prefer the convention (guaranteed by the linter) that $ref is a syntactic shortcut for $merge and that it would just merge metadata. I think it's better to accept a greater degree of conventions instead of trying to enforce strict conformance adding complexity to the language. This way json-schema stays much more succinct and readable. Regarding "allOf", "additionalProperties" and "default" I'm still a little confused and reticent about the topic. Regarding the order of "allOf". I don't understand the relevance when dealing with the "defaults" issue. "allOf" is an array and you can use that to define "default" precedence. @epoberezkin I don't understand why inclusion won't work and I understand that recursion and circular references are necessary I just don't see the problem with them besides serialization. I don't understand the cavets with recursion (I guess you mean circular references) has I believe validations should be done in fully dereferenced schema. This fully dereferenced schema to validate against is js (or any ather language that surelly supports instancing) not json so circular references are not a problem. The only problem would be if you dereference only external references (sometimes is useful for some validator that only reads local references and to have more readable json). Can you explain the problem with fully derefing the schemas? |
JSON schema is language independent. You cannot define validation process relying on self referencing data structures existing only in some languages. So if you cannot de-reference schemas staying in JSON territory then spec cannot do it at all. |
You can not create a validator "in JSON". |
Although that's a situation I haven't contemplated when using "externalOnly" in my dereferencer. |
Correct, but you can define a validation process without referring to any language - that's what the spec should do (and it does)
Yes
Exactly. So it's ok to fully dereference using recursive data-structure in the implementation, but it is not ok to use such terminology in the spec.
It does mean exactly that.
Because it is JSON schema, it should be explained in terms of JSON and other standards, not in terms of any programming languages |
@ruifortes how do you "fully dereference" a recursive / circular reference schema? Here is a simple recursive schema which expresses that a valid instance must be an object, in which all properties are themselves objects (to any level of nested objects) {
"type": "object",
"additionalProperties": {
"$ref": "#"
}
} |
@handrews the idea of @ruifortes is to use self-referencing recursive data structures that exist in JavaScript and some other languages. I just commented on that above. |
@epoberezkin thanks for the clarification, I admit I'm having a bit of trouble following this thread. @ruifortes having re-read this keeping @epoberezkin's comment in mind, yes, he has the right position here: the spec cannot make any assumptions about the language of implementation whatsoever. Not only are there endless approaches to programming languages, but various orthogonal constraints (performance, streaming media processing, constrained environments, etc.) may limit what language features can be used. |
But circular refs is a Json problem that is not specific to json-schema. |
@ruifortes it is indeed possible to construct a recursive object resolving all the references in JavaScript. If you do so, make sure to add "$id" keyword in the included fragments based on the source from which this fragment is taken (or fully resolve $id before inclusion, if it is already present), as otherwise base URI may be incorrect. I find this approach overcomplicated - in my implementation I simply compile schemas to functions and $refs are seen as calls to other functions. That is not a possible approach to define such process in the spec as there is no appropriate standard for recursive data structures (and XML is not an appropriate standard to define JSON schema). So the only sane approach is to see $ref as JSON schema concern and as delegation rather than as inclusion. That's the change that was made from draft-04 to draft-06. |
Well...I'm implementing it now in my dereferencer. I don't think it is complicated at all since "externalOnly" is only useful for optimizing "serialization" (witch is not even an issue with gziped messages) and for readability reasons for cases where a type is extensively used in a schema and it's much more readable if props just $ref it to "#definitions/usedalotschema". |
@handrews I don't have to dereference it to json.
of course, the derefer does this automatically |
@ruifortes you seem to be talking entirely in terms of your implementation, but this repository is about the specification. It is irrelevant to the specification whether a particular implementation can produce some sort of optimization. The specification must be independent of implementations. Can you describe what you want without referring to any aspect of implementation? |
The specifications just has to assume circular $ref exist.
If some programing language can't figure out how to implemented that's a problem with that language not with json-schema. The aforementioned schema should be considered completly valid. Has this one
This is what I thing is the best approach. I'm not just trying to defend my implementation. |
@ruifortes that is a valid schema. What change are you trying to accomplish? |
It assumes that. It just cannot be dereferenced within the spec. JSON-schema is defined in such way that it can be implemented in any language, recursive data structures are not required to implement $refs, neither compiling schemas to functions - there are many ways implementations can follow the spec using constructs available in their languages. Spec has nothing to do with these details though. |
Ok...so we agree. Why not just assume that $ref is a general JSON issue. I'm just saying that json-schema spec shouldn't worry about that. It should just assume $ref works has a general referencing mechanism for JSON and just don't make any assumptions about it. |
What benefit does that provide? |
The benefit is that all the issues regarding $ref, $merge, $use, $extend, path, etc etc are out. |
The reasons not to see $ref as JSON issue:
So while it is possible to create a separate spec for $id, $ref etc. (and actually that's how it was before) it just makes more sense to have $ref in JSON schema. It is already separated from validation by being in the core rather than in the validation doc. $merge/$use, on another hand, can be outside of spec as it is a pre-processing.
How can it "view" data structure as fully dereferenced if it is not possible to fully dereference it? In which terms would it explain such a structure? As I wrote - there is no acceptable standard existing to allow it, and using JavaScript or XML is not acceptable. The only acceptable structure for JSON-schema is JSON - that's the nature of the spec, so $ref should stay as part of the JSON-schema spec. |
json-schema cannot exist without json also. And of course it is possible to "conceptually" view data completly dereferenced. Serialization is just an implementation detail and that's the only problem. json-schema just cannot view it's data has having functions or any other type json doesn't support but $ref's should be seen as real references as in JS or any other language that has them. If the language doesn't have that it's is for the implementation to find workarrounds. |
No, it's purely a data format and not hypermedia. That's why JSON Hyper-Schema exists. It is certainly possible to define JSON Reference separately, and that was done in the past, but it made things more complicated rather than less. JSON Schema only allows it in certain places, which makes it much easier to reason about and makes it possible for JSON Schema to describe itself. Once JSON Schema needs to put usage restrictions on JSON Reference, coordinating the two becomes more of an implementation burden- you can't just use JSON Reference blindly, so JSON Schema implementations must be aware of it whether it is part of that standard or not.
There really hasn't been interest in JSON Reference as a separate thing. The IETF draft expired years ago and despite being quite simple, no one has picked it up. So I'd say it's really not essential in the view of most people. Arguably JSON-LD is a better approach for linking JSON data anyway (LD == Linked Data). |
A specific argument against $ref as JSON extension were schemas like this one, where property name in object is not JSON-schema keyword: {
"properties": {
"$ref": {
"type": "string"
}
}
} In this case $ref is just a property name, nothing special. So "$ref" has only the meaning of reference when used as a property of schema object. If $ref were to be defined for JSON this distinction would not be possible. |
@ruifortes If you want to write your own specification in separation which defines $ref to be whatever you wan, then go ahead. That is not something we are interested in doing, for the reasons we have explained. |
I know the specs state that properties other than $ref should be ignored but I disagree.
One of the most usual situations having a prop that is referencing some general schema type that needs a more specific tittle and description but doesn't make sense to extend that schema just to add metadata.
heres an example props from OCDS (open contrating data standards):
How do the specs suggest we accomplish this? The above could just be syntactic sugar for:
Why not just worry about dereferenced json in json-schema?
The text was updated successfully, but these errors were encountered: