-
-
Notifications
You must be signed in to change notification settings - Fork 270
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
Keywords alongside of $ref
#523
Comments
I wonder how this would interact with #515. I think I mentioned it as a solution somewhere in there. I'll try to find the specific comment and link to it later, but I'm on my phone for the moment. |
@gregsdennis it should be orthogonal. With Otherwise we're into schema merging territory which we will not be discussing here as that's what #515 is for. I'm serious about this, any discussion of topics belonging to 515 on this issue will lead to immediate deletion of the entire comment. I will probably cackle maniacally while doing so, in order to fit the mad dictator stereotype more fully. We don't need another 200+ comment issue, I filed this specifically to keep it separate. |
(it's OK to talk about whether something would put us in merge territory, it's just not OK to drag actual proposals related to merging or similar stuff over here) |
I don't know if it's particularly an issue with this as a feature, but it would be fairly easy to create a contradictory schema. For instance, if a Maybe this is something that we leave to the author to manage, but I figured it should still be mentioned. Another thing that should be mentioned is that these refs could be internal or external. Internal refs are trivial, but I think we should account for the possibility of a |
@gregsdennis in general it is very easy to create nonsensical / contradictory schemas with JSON Schema. The scenario you mention exists today- just wrap the The adjacent keyword behavior is not actually new at all, it just removes an unnecessary Also, the whole point of |
I wasn't trying to bring in new discussion so much as clarify the equivalence in your opening comment. |
@gregsdennis gotcha. Yeah, that was perhaps not as clear as it should be. |
OOOOH. I hadn't realised the implication of making it clear that |
I was thinking on this some more and I realized a neat side effect of using the sibling The example that came to mind was generic classes. If we consider .Net's {
"id" : "http://dotnetschemas.com/list-of-T",
"type" : "array",
"items" : { "$ref" : "#/definitions/T" }
} By itself, this schema would cause an error as {
"$ref" : "http://dotnetschemas.com/generic-list",
"definitions" : {
"T" : { "type" : "string" }
}
} Of course, this particular example would only apply to languages which support generics, but there are likely other "abstract"-type use cases. Maybe... it depends on how the |
The problem is that |
Yeah, @epoberezkin is right @gregsdennis, that wouldn't work. |
This is actually how Doca's {
"$schema": "https://example.com/schemas/doca#",
"id": "https://example.com/schemas/envelope",
"type": "object",
"properties": {
"success": {"type": "boolean"},
"errors": {"type": "array"},
"result": {"cfRecurse": ""}
}
} and then... {
"$schema": "http://json-schema.org/draft-04/hyper-schema#",
"id": "https://example.com/schemas/foo",
"type": "object",
"properties": {
"id": {"type": "integer", "minimum": 1},
"this": {"type": "number"},
"that": {"type": "string"}
},
"links": [
{
"rel": "self",
"href": "foos/{id}",
"method": "GET",
"targetSchema": {"$ref": "https://example.com/schemas/envelope"}
},
{
"rel": "self",
"href": "foos/{id}",
"method": "PUT",
"schema": {"$ref": "#"},
"targetSchema": {"$ref": "https://example.com/schemas/envelope"}
}
]
} For the |
Okay, well, I don't want to get us off-topic, but it was a thought I had. |
I'm assinging this to myself, as I feel it will follow on from #515 . I may actually look to resolve both of these issues with one PR, as I feel they are tightly coupled. |
EDIT: I just realized this isn't what you were talking about, but the below is still important to the issue. I think that it's probably important to define the "merging" behavior for each of the keywords. This is a first attempt:
You could gather annotations from both the current and referenced schemas, so that wouldn't be an issue. What do references in the child (not sub-) schema look like? If I "inherit" from draft 7, and I have a property with a reference to |
@gregsdennis There is absolutely no merging behavior.
|
[EDIT: I was confusing this issue with the $recursive PR, so this didn't make sense, sorry]* |
Well, if we're going to allow Here's an example that attempts to consider the different scenarios we might encounter: Schema A {
"$id":"http://schema/A",
"definitions":{
"arrayMinLength5":{
"type":"array",
"minItems":5
}
},
"properties":{
"justAString":{
"type":"string"
},
"justAnInteger":{
"type":"integer"
}
},
"allOf":[
{"required":["A"]},
{"required":["B"]}
],
"minimum":5
} Schema B
Hypothetical "combined" schema {
"$id":"http://schema/B2",
"definitions":{
"arrayMinLength5":{
"type":"array",
"minItems":5
}
},
"properties":{
"justAString":{
"type":"string",
"minLength":10
},
"newInB":{
"type":"integer"
}
},
"allOf":[
{"required":["A"]},
{"required":["B"]},
{"required":["C"]}
],
"minimum":10
} There might be other scenarios, but I think that covers the basics. |
Also, let's call things "extension" schemas, even though I'm not thrilled with the term, since "child schema" is frequently used to mean a specific subschema that is an immediate child of the current schema object. |
@gregsdennis no, there is no need to do anything of the sort. There is no interaction. At all. None.
These schemas behave completely identically: {
"type": "object",
"properties": {"foo": true},
"$ref": "#/$defs/moreProperties"
} and {
"type": "object",
"properties": {"foo": true},
"allOf": [{"$ref": "#/$defs/moreProperties"}]
} This, in fact, becomes the way to "dereference" a With #514 we changed that internal model to delegation- it's just a normal keyword, and its results get combined with all the other keywords just as they are combined with each other. There is no visibility or interaction through |
If that's the case, then schema authors will have to be very careful to not write contradictory schemas. I'm concerned that this is just a shorthand for placing the I feel that having |
@gregsdennis I appreciate your persistence on this because it's helping show where people might find the new approach confusing.
This exact problem exists now with
This is an assumption that I'm not sure is broadly held. We've been pretty clear that JSON Schema is not OO (whether anyone has listened is debatable, which is a concern). Even the I think the appropriate approach here is that @Relequestual needs to put a very clear statement of the intended usage in PR #585. I have asked for the |
Then what's the benefit of this feature? How is pulling a Having it alongside other keywords implies a different intent (to me that intent is inheritance). A new usage of a keyword should imply new functionality that can't be achieved using the old mechanism. I think that an inheritance-style extension is something that is worth supporting, especially since there are many OO language using JSON Schema. This doesn't require JSON Schema to be OO, however. This has also been pushed by other issues through new keyword proposals like The desire for the functionality is present, and having |
From the opening comment:
Shouldn't we strive to understand why people are doing this and what the expected intent is? |
Because people do it anyway and get confused that it doesn't work. There's even a whole school of thought as shown by several implementations and ambiguous test cases in the test suite that maintains that only adjacent assertions are a problem, and adjacent annotations are not. Without any clear concept of what that means. See json-schema-org/JSON-Schema-Test-Suite#197 and json-schema-org/JSON-Schema-Test-Suite#198. This is not a good situation, and requires clarification. As discussed in #514, we feel that the best approach is to normalize
We will document its purpose explicitly. I am quite confident that not everyone sees it as inheritance, haven spoken with a great many people about this topic. We definitely need to be clear about it, but the solution to people making assumptions is to explicitly state which common/likely assumptions are incorrect, and why. Regarding make JSON Schema more OO-friendly, please do not derail this issue, which is only about Typically, OO analogies are the result of using JSON Schema to generate code. The proposed code generation vocabulary (or rather, the idea of proposing one, it's not there yet) is the appropriate place to address this. Which, like pretty much everything right now, depends on getting vocabulary support solidified in draft-08.
We decided to go with I spent much of the last year exploring every option, use case, and proposal in this area, and scouring the community for people to participate in the discussion. And then doing my absolute best to let everyone have their say, despite some people really not being willing to do anything but throw bombs. I have no desire to do all of that again, as nothing has changed. |
People don't read documentation. That seems to be the main thing. Otherwise, the main use case was overriding annotations (because yes, I did a metric f^&*ton of striving here). Whether or not something was OO-style inheritance has always been equally confusing for people with or without keywords adjacent to |
Updated phrasing to align with current wording. Resolves json-schema-org#514 and json-schema-org#523
An effect of moving to a delegation model for
$ref
(see #514) is that there is no longer any need to forbid adjacent keywords. This was mentioned in passing in the first comment but I wanted to call it out to get clear agreement (without getting bogged down in the very long and nicely resolved #514).The resolution to #514 allows implementations to do inclusions under certain circumstances. This can be made to work with adjacent keywords by simply stuffing the included target under an
allOf
:is equivalent to
If there is already an adjacent
allOf
, the included$ref
is simply appended to the existing list.Any objections? It's extremely common to see people put keywords beside
$ref
even with all documentation saying that it is not allowed, so we really should make it more intuitive.The text was updated successfully, but these errors were encountered: