Skip to content

No other keywords allowed beside "$ref" #197

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

Closed
wants to merge 1 commit into from

Conversation

handrews
Copy link
Contributor

@handrews handrews commented Nov 8, 2017

The spec for $ref, whether in its own JSON Reference spec
or as part of the JSON Schema Core spec, states that keywords
adjacent to "$ref" MUST be ignored. Therefore these tests were
invalid, even though the intent was clear to most readers.

The correct way to combine "$ref"s is with "allOf".

This addresses #113.

@handrews handrews added the bug A test is wrong, or tooling is broken or buggy. label Nov 8, 2017
@handrews handrews requested a review from Julian November 8, 2017 20:27
@handrews
Copy link
Contributor Author

handrews commented Nov 8, 2017

Oops, one of those was actually testing that the adjacent keyword was organizing! That's what I get for not reading descriptions. Will update momentarily.

The spec for $ref, whether in its own JSON Reference spec
or as part of the JSON Schema Core spec, states that keywords
adjacent to "$ref" MUST be ignored.  Therefore these tests were
invalid, even though the intent was clear to most readers.

The correct way to combine "$ref"s is with "allOf".

These tests have probably generally worked b/c "definitions"
is usually processed up front.
@awwright
Copy link
Member

awwright commented Nov 9, 2017

Just looking at a glance, the way it is now is so wrong it makes me wonder if it's that way intentionally.

@handrews
Copy link
Contributor Author

handrews commented Nov 9, 2017

@awwright yeah I was puzzled. I even filed #198 about whether we should be testing to catch this problem (if it is a problem) of definitions being allowed.

Now that we have the assertion vs annotation concept, we could change the $ref description to only forbid adjacent assertion keywords, but allow adjacent annotations? Or... um.. .something. definitions really isn't an annotation either, it's a re-use container. So maybe it's a special case for $ref? I have no idea what the history was here. @Julian do you know?

@inca
Copy link

inca commented Nov 17, 2017

Fwiw we have a use case where we use $id adjacent to $ref as an alias, to dereference one definition from the other.

Example:

{
    "Foo": {
        "$id": "#Foo",
        "$ref": "#GenericObject"
    },
    "GenericObject": {
        "$id": "#GenericObject",
        ...
    }
}

While this works with our validator (ajv) I wonder if this is future-proof — or is it still invalid usage of $ref?

TIA

@epoberezkin
Copy link
Member

epoberezkin commented Nov 17, 2017

@handrews Arguably, definitions is not a keyword. Even though it's reserved in meta-schema, it is just "a standardized location" in the JSON instance that exists and can be addressed unrelated to the position of $ref. There is no reason why these schemas should be invalid.

I think we should really fix the spec to allow at least definitions and annotations together with $ref or better make $ref a normal validation keyword, rather than "fix" this test. As we've agreed that $ref is delegation rather than inclusion I see absolutely no reason to require ignoring anything in the same object.

@inca it is future proof. Even if at some point ignoring definitions or $id alongside $ref will become the default behaviour (which I doubt), there will be an option to not ignore them. I also often use annotation keywords with $ref.

@handrews
Copy link
Contributor Author

As we've agreed that $ref is delegation rather than inclusion

Actually as I've worked out more of how the different keywords need to be treated, I see pros and cons to both. We will discuss it as part of the next draft, not here.

As the spec currently stands, definitions is as much a keyword as anything else, so these tests are incorrect for their versions. If we change that behavior (which I'm open to), then we will change the test cases for that version.

@handrews
Copy link
Contributor Author

@inca based on the current and prior specifications, that behavior is incorrect. $ref processing always happens first, although that is arguably less clear in recent specifications than it was when JSON Reference was a separate draft and therefore obviously needed to be implemented as a lazily-evaluated preprocessing step.

Again, this is a PR for the tests for the spec as written, and is not the place to debate changes to the spec. This topic should be addressed during draft-08 as it fits with the planned theme of that release (re-usability).

@handrews
Copy link
Contributor Author

@inca Having looked at this again (I'd forgotten exactly what this PR was doing already), this change will not impact your use of ajv in any way, nor will it cause ajv to start failing the test.

The problem here is that a conforming implementation is allowed by the current spec to ignore the definitions, which means that the test will fail on some conforming implementations. This is not acceptable, and is unfair to people who implemented the spec to the letter, even if we don't like the current spec.

@Julian
Copy link
Member

Julian commented Nov 18, 2017

So yeah this one's definitely me, and was definitely "intentional" in that I've had people ask about it in the past and responded that my reading of the spec at the time was that this was fine and allowed :)!

I'm happy to be overruled if others feel that isn't the case.

But essentially my reasoning was that there's a difference between JSON Schema saying that $ref should make implementations ignore $ref for validation and saying that properties that are clearly present there are not addressable -- i.e., if you reference something with a pointer, it's clearly there, and you can index into it, implementations do not have to pop all the items out of a thing rather than simply only applying one validator.

Again though, happy to be convinced (or just defer) that the spec in fact doesn't allow this.

@@ -125,7 +125,7 @@
"b": {"$ref": "#/definitions/a"},
"c": {"$ref": "#/definitions/b"}
},
"$ref": "#/definitions/c"
"allOf": [{"$ref": "#/definitions/c"}]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IIRC allOf isn't in draft 3.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

... and that's another good reason to close this. I forgot that draft-03 had extends or something.

@Julian
Copy link
Member

Julian commented Nov 18, 2017

Here's the last time this came up, with in fact both you @handrews and @awwright participating :)

I'm guessing that there's a slight nuance here in that you're I guess talking specifically about how since definitions is one of the "validators" that that means you need to remove it, but I think my initial intuition is the same -- you remove it for "validation" (which definition in fact does not do), but the thing is there, if you reference it somehow, it's fine, even under the old specs.

But yeah, if there's consensus, happy to defer.

@handrews
Copy link
Contributor Author

@Julian given the history I think we should actually stick with what's there. Particularly given the work in draft-07 that starts classifying keywords into assertions and/or annotations, I was already intending to pursue that further in draft-08. And definitions is one that specifically does not fit either classification (really, it belongs with $ref as it pretty much exists to be the recommended target of intra-file $ref-ing). So I'm going to close this and we'll follow up with clarifications in draft-08.

@handrews handrews closed this Nov 18, 2017
@Julian
Copy link
Member

Julian commented Nov 19, 2017

Sounds reasonable to me!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug A test is wrong, or tooling is broken or buggy.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants