Skip to content

$ref (and kin) across schema versions #808

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
gregsdennis opened this issue Oct 7, 2019 · 19 comments · Fixed by #914
Closed

$ref (and kin) across schema versions #808

gregsdennis opened this issue Oct 7, 2019 · 19 comments · Fixed by #914
Assignees
Labels
clarification Items that need to be clarified in the specification Priority: High

Comments

@gregsdennis
Copy link
Member

gregsdennis commented Oct 7, 2019

The spec doesn't define (and also doesn't mention that the behavior is undefined) how the reference keywords (e.g. $ref) work when referencing into schemas declaring other spec versions.

Example 1

I define schema http://my.com/schema as a draft 7 schema, but I need to reference schema http://that.one.guy.com/schema for one of my properties. Happily, that guy's schema is also defined at draft 7.

One day in the not-to-distant future, that guy upgrades their schema to draft 2019-09. Now my draft 7 schema (without being altered) references a draft 2019-09 schema.

Example 2

I define schema http://my.com/schema as a draft 7 schema, but I need to reference schema http://that.one.guy.com/schema for one of my properties. Happily, that guy's schema is also defined at draft 7.

One day in the not-to-distant future, I upgrade my schema to draft 2019-09, but it still references a draft 7 schema, which I don't control.


How is the validator supposed to handle this?

Ideally, I'd think the validator would take each schema document separately, and (if it supports the draft declared by the document, otherwise error) it would evaluate the reference under the draft it declares. However, I can see where a validator would get this wrong and evaluate the entire reference tree based on the draft declared by the root schema.

This should be either defined or explicitly stated that it's undefined.

@awwright
Copy link
Member

awwright commented Oct 7, 2019

The behavior of a schema doesn't change depending on how it is loaded (except, of course, any under-specified relative URI references in the document). So a schema marked 2019-09 will always have that behavior, even if referenced from a schema using a different version.

I don't know if this is specifically called to attention, I think it should be self-evident though.

Now one thing we are missing is tests for this (iirc), so maybe there are implementations that do it differently. We don't break reverse compatibility though (not purposefully, at least), so I'm not sure there's really a way to even test for this. (In the cases where we do remove features, implementations may still support the old behavior the same way they can support custom extensions.)

@gregsdennis
Copy link
Member Author

I have a PR in the test suite that tried to do this. It's old enough now that it should be closed if it's not already.

I think we have enough diversity in versions and published schemas that we should say something in the spec. Assuming something is self-evident has historically bitten us.

@Julian
Copy link
Member

Julian commented Oct 7, 2019 via email

@johandorland
Copy link
Collaborator

Some validators already support multiple versions detect the schema version based on the $schema that is at the root of the reference document, which is the most sane thing to do and the solution @gregsdennis proposes. I'm all for describing this behaviour more explicit and thus adding it to the spec. I would make this optional as you want to avoid the scenario where in order to create a new draft 2019-09 implementation you would also have to implement all previous drafts.

@handrews
Copy link
Contributor

handrews commented Oct 8, 2019

@johandorland is correct on the right way for this to happen.

In general, § 8.1 Meta-schemas and vocabularies, makes it more clear than ever that $schema (and, if present in the referenced meta-schema, $vocabulary) should control how a schema is processed.

§ 8.1.2.1 Default vocabularies covers some specific cases of how implementations should behave.

§ 8.2.4.5 Loading a referenced schema is the most relevant section to this specific question. We could easily add a sentence or two to the effect that each loaded schema's $schema should be respected independently.

@handrews handrews added this to the draft-08-patch1 milestone Oct 8, 2019
@handrews
Copy link
Contributor

handrews commented Oct 8, 2019

I would make this optional as you want to avoid the scenario where in order to create a new draft 2019-09 implementation you would also have to implement all previous drafts.

We should put this in a patch/bugfix draft (I just made a milestone for it), in which case we don't want to require any behavior.

In general, I thinking implementations at least SHOULD check $schema and if available $vocabulary, but are free to error out on unknown or known but unsupported (e.g. old drafts) values.

@handrews handrews self-assigned this Oct 10, 2019
Relequestual added a commit to Relequestual/json-schema-spec that referenced this issue Feb 3, 2020
…d differently MAY be supported, or an error SHOULD be thrown

Fixes json-schema-org#808
@Relequestual
Copy link
Member

@handrews Attempted to resolve this. Please provide feedback =]

@Relequestual
Copy link
Member

Relequestual commented Feb 5, 2020

PR Updated.

  • Awaiting new related issue for overhall of "How to load a schema".

Otherwise, LGTM!

@handrews
Copy link
Contributor

handrews commented Feb 5, 2020

@Relequestual See #849.

@handrews
Copy link
Contributor

handrews commented Feb 6, 2020

@gregsdennis @Relequestual @awwright @Julian @johandorland see also #850 which deals with changing $schema at a resource boundary in addition to a $ref, since there isn't supposed to be any functional difference between embedding or referencing a full schema resource.

@Relequestual
Copy link
Member

#914 claimed to close this issue (and did so automatically), but I don't think we addressed specifically references across different versions.

I think we probably still need to address this, and my feeling is, as @handrews said...

I think we should say no, if you want to use draft-04 with draft 2020-NN, you have to $ref it.

Do we need to explicitly state that in the spec, or would it be better as "additional info" on the website?

@Relequestual Relequestual reopened this Jul 3, 2020
@gregsdennis
Copy link
Member Author

I'd go with explicitly stating in the spec.

@Relequestual
Copy link
Member

Relequestual commented Jul 4, 2020

We allow embedding a schema resource without declaring it's $schema, as it's assumed to be the same as the enclosing document. For referenced schemas, if the referenced schema doesn't declare $schema, the behaviour is application defined, which in most cases will be defaulting to the latest version the application supports.

Additionally, we say that...

Meta-schemas that do not use "$vocabulary" SHOULD be considered to
require this vocabulary as if its URI were present with a value of true.

This issue is tricky to resolve without defining a lot of behaviour as application defined, if we want to enable as much backwards compatibility as possible. However, we don't... my feeling is we want to discourage the use of draft-4 as much as possible.

I would imagine the aim of this phrasing was to enable other dialects to, by default, be based on the core vocabulary (which iirc is required anyway).

But, also with this phrasing, when an older version of JSON Schema is used, where it's accepted meta-schema does not declare a vocabulary, SHOULD be considered to support 2019-09 core vocabulary. This situation is likely the right situation to be exempt from the SHOULD requirement.

As such, we need to define something like...

Any embedded or referenced schema resouce which identifies as using a known meta-schema which relates to a known dialect, but that doesn't define voacbulary support using `$vocabularies`, MAY be processed using the feature set defined by the dialect. Such supoort is application defined. (While many implementations support multiple drafts of JSON Schema, schema authors SHOULD NOT assume support of referencing or embedding JSON Schema resources which use a feature set defined by prior drafts of JSON Schema, which includes draft-04.)

We could add a CREF or probably more preferable, an apendix section which shows an example.

I think we have HAD a few examples in other issues and PRs, and maybe @jdesrosiers would be best placed to provide such examples in an apendix section to demonstrate the levels of possible support.

Sound reasonable?

@jdesrosiers
Copy link
Member

#914 claimed to close this issue (and did so automatically), but I don't think we addressed specifically references across different versions.

I think it does cover references. We've defined embedded schema to be equivalent to references, so the behavior defined for embedded schemas should be equivalent to the behavior for references.

I think we should say no, if you want to use draft-04 with draft 2020-NN, you have to $ref it.

I see no reason to restrict draft-04 from being embedded. You just need to consider $schema and id/$id together instead of just looking for $id.

I think we have HAD a few examples in other issues and PRs, and maybe @jdesrosiers would be best placed to provide such examples in an apendix section to demonstrate the levels of possible support.

I could put together an appendix, but it might take a while for me to get to it. I haven't had a lot of free time recently.

@Relequestual
Copy link
Member

Relequestual commented Jul 9, 2020

I GUESS embedding any resource draft version is OK if it identifies itself. All schemas must identify themselves with $schema. THAT defines the feature set to be used for processing the schema resource.

The SHOULD requirement (quoted in the comments above) in the vocabulary assumptions in the associated meta-schema allows the flexibility to NOT do that if it's justifiable to do so.

OK. I don't think we're in any rush here, and we're pretty slow moving on the spec right now... (Talking personally).

Would you like to put out a gestimate on that work?


We could de-prioritise this issue if we agree that the resolution won't require any specification change, but simply additions to the appendix.

@Relequestual
Copy link
Member

If we need an alternative name in some cases, "primary" can be for more than one thing.

@Relequestual
Copy link
Member

@gregsdennis
Copy link
Member Author

I think the paragraph starting at L1885 addresses this more directly. The rest is fallout and is fine by me.

@Relequestual
Copy link
Member

Relequestual commented Oct 15, 2020

Ok, I'll close this issue on the assumption that #977 will be merged without significant changes.

@gregsdennis gregsdennis added clarification Items that need to be clarified in the specification and removed Type: Maintenance labels Jul 17, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clarification Items that need to be clarified in the specification Priority: High
Projects
None yet
7 participants