nickcmaynard / jsonschemalint

JSON Schema Lint. Like you I'm busy, so pull requests will get merged quicker than feature requests are implemented.
https://jsonschemalint.com
MIT License
80 stars 31 forks source link

Future changes to JSON Schema #14

Closed HotelDon closed 7 years ago

HotelDon commented 7 years ago

So there have been a few changes to roadmap for JSON Schema in the last couple months - for one, v5 of the spec has added no new features, and was instead done to clarify a bunch of language in the spec for future improvements. This means that the features originally meant for draft 5 have been pushed to draft 6 and beyond. Currently, work is being done on draft 6, but some features (including the $data keyword) are being tabled until draft 7 or later in order to allow more discussion of potentially controversial changes.

So, in the mean time, I want to work on some changes to JSL to clarify a few things and prepare for the future. Firstly, drafts 4 and 5 are now functionally the same, so those should probably be combined as "draft-04/05" or "draft-04/draft-05" on the drop down menu. Version 5.0.0 of AJV will support most of the v6 proposals, and will likely be done sometime in January - so adding draft-06 to the list should be easy.

However, that does leave the keywords destined for draft 7+ in a bit of a weird spot - most of them are being moved out of AJV proper and into ajv-keywords until those specs start getting worked on (it also includes a some custom keywords, and any keywords that end up rejected might end up in there as well). Conversely, the $data keyword is being broken out into it's own run time option, which will only work in v5+. So I propose adding an "experimental" entry on the drop down menu that enables these keywords for anyone who wants to use them, as a sort of "draft-n+1".

I was going to start working on it today, but since I'm waiting on the next version of AJV to be finished anyways, I figured I'd ask for your input first - any suggestions or concerns are appreciated.

HotelDon commented 7 years ago

So, it turns out that there aren't really any changes in draft-06 that break backwards compatibility - so the next version of AJV will support drafts 4,5, and 6 by default without needing any special options. However, this means if you wanted an option to validate to draft-04/05 only, you'd have to use a different validator (or keep the old version of AJV around, but that's a messier option). I'm not sure how important keeping that separation would be, but I'll leave that for you to decide.

nickcmaynard commented 7 years ago

Hey. Thanks for the detailed thoughts. I'm on holiday right now, but promise I'll have a think and get back to you as soon as I'm back.

nickcmaynard commented 7 years ago

Up until now, I haven't paid a lot of attention to the differences between draft-04 and draft-05. The hard isolation was added mostly because of the (hideous) breaking changes between IIRC draft-03 and draft-04. So I now, by default, isolate every version.

So... are they retrospectively changing the definition of draft-05 to, in essence, be draft-04 + $data? Or have I misunderstood that?

nickcmaynard commented 7 years ago

FYI, big refactoring going on right now in componentise, so please base any changes on that.

HotelDon commented 7 years ago

Draft-05 doesn't include the $data reference in the spec - nothing was added to draft-05 at all. In fact, $data isn't planned for draft-06 either, but it will probably get in eventually (it's definitely getting added as a hyperschema keyword at some point). I was only talking about $data support as far as AJV is concerned, and that comment was written before I learned that AJV isn't doing version flags anymore - instead, it just loads the draft-06 meta-schema by default, and you can load the draft-04 schema (which is also the draft-05 schema) instead if you need it. As a result, the $data option will work with either.

nickcmaynard commented 7 years ago

OK. So draft-04/05 are identical. Draft-06 is a moving target which AJV will track. But - although we can load draft-04/05 meta schema (for validating our schemas) the actual language support won't change.

So - if we validate a scheme against the appropriate meta schema, then if that fails (i.e. draft-04/05 target, but draft-06 keyword) then we should refuse to attempt document validation, as the schema is invalid.

Does that sound workable? If so, from what you describe we can switch AJV into draft-04/05 meta schema mode and effectively have a draft-04/05 compliant validator. Or have I misunderstood?

HotelDon commented 7 years ago

Yes, that should work. I've already done some work setting things up (although I need to move those changes over to the componentise tag), so I should be able to test that tonight to make sure there aren't any weird edgecases hiding in there.

nickcmaynard commented 7 years ago

Great, thanks. I'll try to close off the componentise work tomorrow so you don't have a moving target.

nickcmaynard commented 7 years ago

Looks like draft-04 and draft-05 have different meta-schema. So let's keep those isolated for now.

HotelDon commented 7 years ago

Do you have a link to the draft-05 meta-schema? Because json-schema.org still lists the draft-04 meta schema as the latest.

nickcmaynard commented 7 years ago

It's included in AJV apparently - https://github.com/epoberezkin/ajv/releases/tag/5.0.1-beta.0

HotelDon commented 7 years ago

So that meta-schema is the one that was created specifically for AJV to support the old v5 proposals - there never was an official v5 meta-schema. When you pass the v5: true option to AJV, it would just swap out the official v4 meta-schema for that one. AJV still includes it for backwards compatibility reasons. You could include that as an option, but calling it "draft-05" would be really confusing since there would be no continuity between it and draft-06.

nickcmaynard commented 7 years ago

Branch merged. Do you have any links where these draft versions are discussed?

HotelDon commented 7 years ago

There was a pull request (json-schema-org/json-schema-spec#132) that references the fact draft-05 didn't update the meta-schema, and that some of the updates originally meant for it are being pushed to draft-06. Unfortunately, I can't find the exact discussion where this decision was made (I'm pretty sure it's hidden somewhere in the issue tracker), but I know that @awwright or @handrews can explain the reasoning behind the decision themselves if you message them about it.

handrews commented 7 years ago

@HotelDon @nickcmaynard At this point we're just moving to Draft 06 because it is very close to completion (I am optimistic for February). @awwright did not want to publish a meta-schema with Draft 05 because it was a cleanup more than anything else- there was some discussion among various of us at json-schema-org/json-schema-spec over following up with one but by now Draft 06 is just a better focus.

The TL;DR here is that we're going to heavily encourage people to implement Draft 06 and give feedback on it, rather than spending time trying to make Draft 05 a major presence "in the wild."

Draft 06 validation is nearly complete- I think the biggest remaining validation PR is on how to spell the new formats ("uri-ref", "uri-template", "json-pointer" vs "uriref", "uritemplate", "jsonpointer", with the hyphen forms having more support due to the existing "date-time"). Everything else with Draft 06 is about wording clarifications or hyper-schema, I'm pretty sure.

nickcmaynard commented 7 years ago

OK. I get the rationale there. I guess my mistake was implementing draft-05 at all. What this means, though, is that I have a bunch of users used to using draft-05 as it currently stands in AJV, and I'm not happy about pulling the rug out by clobbering that. What's the official line on draft-05?

nickcmaynard commented 7 years ago

@handrews Thank you for pitching in.

HotelDon commented 7 years ago

The Experimental option I've added currently enables almost all the features that were in draft-05 that are currently in limbo - AJV moved them into a separate package (ajv-keywords) but the functionality is still there for those who want it.

nickcmaynard commented 7 years ago

If we could have an "official" draft-05 metaschema that would solve our problem I think. If not, I think we're forced to use the next best thing, and that's the (inaccurate? Out of date?) one that AJV includes, but is AFAICS the de facto draft-05. Thoughts?

HotelDon commented 7 years ago

Loading the draft-05 meta-schema is easy enough, I just need to make sure that it works without any extra tweaking. I'll let you know if I run into any problems. I would still recommend against calling it "draft-05" - maybe "draft-05 (deprecated)" or something so people who go looking into it aren't super confused.

handrews commented 7 years ago

@nickcmaynard if you want an unofficial one I worked one out, I'm sure I still have it lying around somewhere. I haven't looked at the "draft-05" schema in AJV, don't know if it's really the published draft-05 or whether it is an approximation of what was proposed for draft-05 years ago before the project stalled (@epoberezkin care to comment?) (@Relequesual you may also find this thread of interest)

But yeah, I would actually recommend working off of the almost-there draft-06 stuff before recommending draft-05. If you're doing hyper-schema that's tricky (also, if you're doing hyper-schema stuff I'd love to know about it).

epoberezkin commented 7 years ago

@HotelDon Conversely, the $data keyword is being broken out into it's own run time option, which will only work in v5+.

Actually, with any version.

However, this means if you wanted an option to validate to draft-04/05 only, you'd have to use a different validator

Not really necessary. It's enough to set meta-schema for that draft as a default meta-schema and Ajv will work just fine. It'll all be explained in migration doc, it's partially explained here already: https://github.com/epoberezkin/ajv/releases/tag/5.0.1-beta.0

@nickcmaynard So - if we validate a schema against the appropriate meta schema, then if that fails (i.e. draft-04/05 target, but draft-06 keyword) then we should refuse to attempt document validation, as the schema is invalid.

correct

I have a bunch of users used to using draft-05 as it currently stands in AJV, and I'm not happy about pulling the rug out by clobbering that.

That won't be necessary, it can be an extra option in JSL. Ajv still refers to it as v5 rather than draft-05 because it was not standardised and there wasn't any timeline in JSON-Schema org at the time. So you can have something like this list:

$data support and other keywords that may be added in the future (e.g. if/then/else etc.) can be added with "experimental" toggle (but you can make that your "Ajv v5" option already has $data and the keywords that are defined now in Ajv with v5 option). It is indeed a bit messy, so I am trying to clean it up by version 5.0.0 of Ajv but I am doing it in such a way that migration should be relatively painless - just tweaking options of Ajv instance and making some extra calls during initialisation, so you should be able to do the same - I can help.

HotelDon commented 7 years ago

@epoberezkin Yeah, I realized after my initial comment that I was wrong on those two points. I had misread some of the documentation and totally goofed there. I haven't pushed any of my commits up yet, but everything from draft-04 up will use Ajv - once I figured out you could just swap out the meta-schema manually, I scrapped the empty text file that was going to resurrect Is-My-Json-Valid.

As for draft-05, "v5 (Ajv)" would be a good label, since it distinguishes it from the other options which all refer to official draft versions directly. The page can just include an explanation at the bottom for anyone who is confused by that choice.

epoberezkin commented 7 years ago

Yep, I see now...

nickcmaynard commented 7 years ago

@HotelDon Sounds good. Let's keep draft-05 (the route will still need to work, too), but run with some new labelling "draft-05 (Ajv v5, deprecated)" as suggested.

Thank you everyone for your help.

awwright commented 7 years ago

@HotelDon @nickcmaynard There's not technically a "v5" of the spec yet -- the October draft-wright-json-schema-00 release entirely replaces the old draft defining draft-04, and nothing more.

draft-05 is supposed to refer to the next meta-schema, but it's sort of ended up referring to what's properly called the draft-wright-json-schema-00 I-D.

nickcmaynard commented 7 years ago

Well, this is as clear as mud.

@awwright Did you manage to read this whole thread, and do you agree with the conclusions we've made?

On another note, perhaps it would be a good idea (if not for those developing tools for JSON schema, then for the end users) if json-schema.org put out an official history document on the spec. It's not especially... intuitive.

handrews commented 7 years ago

@nickcmaynard: @awwright sometimes seems to agree with @Relequestual and I that the draft-wright-json-schema*-00 drafts should be referred to as Draft 05 and sometimes does not. (see here, here, and here, and you will understand that discussion as well as I do).

The history idea has been discussed at json-schema-org/json-schema-org.github.io#54 which was closed after putting up a wiki page but I'm arguing in favor of putting something on public-facing site as well.

awwright commented 7 years ago

@nickcmaynard Yeah, sorry if it seems like I'm sort of dancing around issues, I'm trying to avoid telling particular implementations how they should work.

Looking at the implementation, I would simply rename "draft-05" to say "experimental features".


So to preface a brief history, technically a new Internet-Draft entirely replaces an old I-D upon publication, and when published, old drafts cease being a thing that anyone should implement. So I don't think it's really worth it to go over a whole history of JSON Schema or past versions -- except for historical interest.

Of course, occasionally you have to support documents written for past versions, JSON Schema allows implementations to implement custom keywords, and support for keywords removed since past versions falls under this. And a JSON Schema linter falls under "historical interest," to be sure, since we're dealing with documents that may have been written for very old implementations.

draft-zyp-json-schema-00 was published 2009-12-05 and was immediately replaced by draft-zyp-json-schema-01 which fixed a few publication mistakes.

draft-zyp-json-schema-02 was published 2010-03-23 and changed some keywords: s/maxDecimal/divisibleBy/, uniqueItems, and some hypermedia changes

draft-zyp-json-schema-03 introduced meta-schemas, and designates a set of meta-schemas with a "draft-03" designation, copying the draft number. It also refers to previous drafts as e.g. "draft-01" even though there's no meta-schema URI for those. It split apart hyper-schema from validation functionality, giving each a meta-schema URI.

The concept of the meta-schema was introduced presumably to declare the need for a particular vocabulary -- like use of keywords that an implementation might not yet support.

JSON Schema only defines a meta-schema URI, there is no authoritative meta-schema document, only an informative one published through different channels (the official JSON Schema website).

Last October, I published the new documents and so the IETF gave the new designation draft-wright-json-schema-00 (resetting the number). The document was simply intended to rephrase the semantics of draft-04 in cases where it was either ambiguous or outright incompatible with other standards. However, it also eliminated all references to a meta-schema URI, making it unclear what URI/designation to use. This was unintentional, the correct meta-schema is draft-04.


Internet-Drafts are requests for feedback from implementors, and themselves proposals. As such, it doesn't really make sense to talk about a "proposed feature" that's not actually in a published Internet-Draft.

Things that aren't in the I-D are just custom extensions, and should probably specify a vendor (like the author of the issue, or the implementation it first appeared in).


What AJV's draft-05 is referring to isn't even the latest draft, but a series of features that will presumably make it into the next meta-schema. The next meta-schema was going to be called draft-05 (but now we're not so sure).

So, I would simply rename the "draft-05" option to "experimental features" and call it a day.

Hopefully that clarifies some things, please let me know!

epoberezkin commented 7 years ago

What AJV's draft-05 is referring to isn't even the latest draft, but a series of features that will presumably make it into the next meta-schema. The next meta-schema was going to be called draft-05 (but now we're not so sure).

@awwright I don't even call it draft-05, it's "v5"... :) And this terminology goes away with the next major release to avoid any confusion, the features will be available though as plugins/options.

nickcmaynard commented 7 years ago

Basically, I should never have touched v5. My bad.

OK. Here's a proposed approach. From now on, jsonschemalint.com will only validate against:

  1. Published versions from json-schema.org
  2. The magic v5 from Ajv, previously known as "draft-05", to be renamed to "out-of-spec v5 (Ajv)"

This'll have to be done in several phases:

  1. An immediate change to:
    • Rename draft-05 to "out-of-spec v5 (Ajv)", v5 for short routes, along with routing forwarding (draft-05 -> v5).
    • Add a warning to v5 pages about out-of-spec-ness, with a recommendation to use the latest published version.
    • Change the default version to draft-04 (the latest published version).
  2. Whenever a version is cut by json-schema.org (next draft-06, draft-wright-json-schema-01, or whatever it's being called) is added, we'll add that as the new "default" version. @awwright Please could json-schema adhere to a single naming standard from now on, to make this more manageable? Perhaps json-schema could have "official" version naming with mappings to IETF versions? If there was a history webpage with the information you've written above (as well as the mappings) that we could point to, that would be ideal.
  3. We may add experimental features. They will always be a non-default option that must be expressly selected by the user - probably as an "experimental" spec version. This will be defined as a moving target, completely unversioned, and will carry an appropriate on-screen warning. Any saved Gists using this route will thus have an ephemeral target.

Can anybody see any gaps in this? I was tempted to redefine draft-05 as "experimental", thus unfreezing it, but I have pre-existing saved Gists, users with bookmarks, etc. I'm not sure how that would work in practice... so I'm willing to leave that as an oddity of history.

handrews commented 7 years ago

@nickcmaynard the IETF drafts have their own naming rules, hence draft-wright-jsonschema-*-00 (note that Draft 04's validation spec was actually draft-fge-jsonschema-validation-00, so this is not new).

The meta-schemas use a consistently incremented number. That's where the 4, 5, 6, etch. comes from. We're going to skip 5 because we all confused ourselves over it (@awwright may have a slightly different view but I think I'm accurate representing the rest of the project here, and in any even we're all ending up at the same place).

handrews commented 7 years ago

NOTE: I meant meta-schema above, not hyper-schema. I edited the comment but commenting again for people who are only reading email notifications.

epoberezkin commented 7 years ago

@nickcmaynard Yeah, v5 is a bit of an oddity :) My bad... But it was serving as a substitute to a proper spec evolution as the spec had been stagnant for quite some time.

I think it's fine to have v5 "crystallised" for backward compatibility - I will put all the settings/calls necessary for "v5" with the next version of Ajv in the migration doc. As I wrote, I would hide it from the drop-down so people don't select it accidentally. But it's up to you...

If "experimental" is going to mean $data and additional keywords from ajv-keywords it won't be that much of a moving target - it will stay [mostly] backwards compatible. But I think it's fine for "experimental" if things occasionally break.

By the way, "experimental" could be some check box to be an extension of a specific JSON schema version (04, v5, 06, etc.) rather than a separate option. This way it will be less of a moving target. But it's up to you of course how to do it and whether you do it at all...

@handrews: the IETF drafts have their own naming rules, hence draft-wright-jsonschema-*-00 (note that Draft 04's validation spec was actually draft-fge-jsonschema-validation-00, so this is not new).

yep, I think it's still fine to use draft-06 etc.

HotelDon commented 7 years ago

@nickcmaynard I can change all references to draft-05 to v5 easily enough. Not sure of the best way to add an alert to specific pages though (edit: oops, the answer was staring me right in the face on that one). The default version in my pull request will be draft-06, since my original plan was to merge these changes after draft-06 went live - if you want to release an interim version in the mean time, that's fine, but it feels like most of the damage has been done and waiting another few weeks wouldn't kill anyone.

@epoberezkin I'm having some trouble loading the v5 schema - this is the code I'm using, which to my understanding, should work (schemas.v4 and schemas.v5 are objects containing the schemas for draft-04 and v5):

validator = ajv({
    verbose: true,
    allErrors: true,
    meta: version === "draft-04" ? schemas.v4 : 
          version === "v5" ? schemas.v5 : true,
    $data: version === "Experimental"
});

The meta: schemas.v4 (edit: actually no it doesnt, it actually acts like draft-06) and meta: true cases both work fine, but for meta: schemas.v5, I get this error in the console: 'Error: no schema with key or ref "http://json-schema.org/draft-04/schema#" '. Any ideas where I'm going wrong with this?

epoberezkin commented 7 years ago

@HotelDon Please see Migration section here: https://github.com/epoberezkin/ajv/releases/tag/5.0.1-beta.0

HotelDon commented 7 years ago

Thanks 👍 I missed the migration section at the bottom.

awwright commented 7 years ago

@nickcmaynard @HotelDon @epoberezkin I would highly advise against referring to any numbers greater than 4 (like "v5") as no such things have been published yet -- and there's no guarantees a feature will be written into a draft until it's published.

Anything that's not in a published meta-schema, I would just call "experimental".

I don't know if I made this very clear, but the meta-schema and the Internet-Drafts are different things and have different namings. A published I-D defines a meta-schema URI to use, and from time to time we might update or clarify an existing meta-schema with a new I-D publication (for example, to fix a typo or issue a clarification -- this is what draft-wright-json-schema-00 did to draft-04).

HotelDon commented 7 years ago

@awwright No code that references draft-06 (or whatever it ends up being called) is getting pushed to the main site until the next draft is published. At that point, all of the UI labels will be updated if needed and the new version of the site will go live (unless @nickcmaynard has anything else he wants to add in at the last second). That's been my plan the entire time.

As for referencing "v5", well, that's a necessary evil at this point. I chose the name "Experimental" to alert people not to expect any backwards or forwards compatibility with features they find there - and v5 mode is for backwards compatibility with what is now a nonstandard implementation (I don't know how many people are currently using the draft-05 option, but cutting them out of the picture has a non-zero cost associated with it). So keeping them separate is important. Whether it's "v5 (AJV)" or "v5 (deprecated)" or "v5 (Don't use this)", it has to include the number so people who had previously used the "draft-05" option know what it's referring to.

nickcmaynard commented 7 years ago

@awwright I get that each I-D points to exactly one meta schema. However, I'm far from happy that a published meta-schema (ie. draft-X) might change. That's going to break all the validation libraries, not just jsonschemalint.com. Did I misunderstand that?

epoberezkin commented 7 years ago

Thanks 👍 I missed the migration section at the bottom.

@HotelDon you didn't, I've just added it :)

awwright commented 7 years ago

@nickcmaynard I don't think there's any reason anyone should ever see breakage. Any time there's a change in actual functionality, there should be a new meta-schema URI and document published.

The nature of the Internet-Draft process just means that drafts are published through a different mechanism than the meta-schemas, and a new I-D can be issued at any time when feedback is desired; and sometimes these changes are merely typo fixes or a clarification of non-normative language so no meta-schema change is necessary.

Published meta-schema documents, like the I-Ds, will not be changed (only superseded).

nickcmaynard commented 7 years ago

@awwright OK, thanks. I read "from time to time we might update or clarify an existing meta-schema" as "we might change an existing meta-schema". Which obviously would be bad. If I'm reading it correctly now, what you've described is about documentation for the meta-schema.

awwright commented 7 years ago

Oh yeah, I didn't intend to say it that way. You've got it exactly right!

On Jan 19, 2017 8:35 AM, "Nick Maynard" notifications@github.com wrote:

@awwright https://github.com/awwright OK, thanks. I read "from time to time we might update or clarify an existing meta-schema" as "we might change an existing meta-schema". Which obviously would be bad. If I'm reading it corectly now, what you've described is about documentation for the meta-schema.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/nickcmaynard/jsonschemalint/issues/14#issuecomment-273807910, or mute the thread https://github.com/notifications/unsubscribe-auth/AAatDZ_6A4UWXhEKwFxbwsJ3Tt3I2t2lks5rT4KmgaJpZM4LUihH .

Relequestual commented 7 years ago

Chiming in here, late to the party...

We agreed (somewhere, I forget where) that we would avoid publishing a draft-5 meta-schema to discouridge people from using draft-5. This will be a lot easier when draft-6 is released (WITH a meta-schema).

Most people are using draft-4 in production now anyway, so hopefully before talk of draft-5 trickles down to lirabry writers, and users, draft-6 will happen and look much more appealing... I hope.

nickcmaynard commented 7 years ago

OK - draft-05 has been pulled. Let's put this on hold until draft-06 is out.

HotelDon commented 7 years ago

If by "put this on hold", you mean "take a break because most of the work is already done", then yes, I agree. See HotelDon@afe24e9 and look things over - I did my best to follow your coding style, but if there's anything else you want me to clean up, let me know. I would have made the PR but I'm going to have to update the dependencies when draft-06 is released and Ajv 5.0 comes out of beta, so I'll just wait until then.

nickcmaynard commented 7 years ago

I mean - let's wait until draft-06 is official. Drop a PR if you like, but we won't merge/deploy until draft-06 is cut. Not playing that game again! :-)

nickcmaynard commented 7 years ago

@HotelDon changes look good, though :)

nickcmaynard commented 7 years ago

@handrews Given your comments about draft-05, I would suggest removing it from the wiki: https://github.com/json-schema-org/json-schema-spec/wiki/Specification-Links Well - the draft-05 bit, anyway, or adding some gotchas...