Skip to content
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

Move "definitions" to core (as "$defs"?) #512

Closed
handrews opened this issue Nov 28, 2017 · 20 comments
Closed

Move "definitions" to core (as "$defs"?) #512

handrews opened this issue Nov 28, 2017 · 20 comments
Assignees
Labels
clarification Items that need to be clarified in the specification core Priority: Medium validation

Comments

@handrews
Copy link
Contributor

In #505 I commented that definitions fits better into core than validation (and @Anthropic agreed).

The point of definitions is simply to reserve a keyword under which you can safely collect named schemas, without worrying that they will get accidentally interpreted by an extended vocabulary.

definitions also allows packaging multiple schemas in a file for re-use as $ref targets without having to explicitly assign $ids. In that sense, it is most closely associated with $ref and $id, both of which are part of core.

Furthermore, having a designated re-use location has nothing to do with validation or any other particular JSON Schema use case. Reading through the validation spec it seems quite out of place. For the last several drafts, there has even been a specific note in its description that it does not affect validation.

When you have to explain how the keyword has nothing to do with the purpose of the specification, that's probably a sign that the keyword is in the wrong place.

Anyone seriously object to moving this?

@erayd
Copy link

erayd commented Nov 28, 2017

Moving this into core sounds like a good idea. Core makes much more sense as a logical home for the definitions keyword, as the keyword itself doesn't actually imply any action - it's simply a well-known location where schema definitions may be stored.

In order to maintain consistency with other core keywords, it seems sensible to rename it to $definitions. Doing so will improve obviousness going forward, and seems unlikely to adversely impact users.

@handrews
Copy link
Contributor Author

@erayd I suppose there wouldn't be any harm in officially reserving $definitions and perhaps deprecating definitions but noting that extension vocabularies MUST NOT give it different behavior. It's not like references to #/definitions/... would stop working :-P

@erayd
Copy link

erayd commented Nov 28, 2017

@handrews That sounds like a good idea.

@erayd
Copy link

erayd commented Nov 28, 2017

On a related note, would it also be possible to specify that arbitrary schema fragments SHOULD NOT appear outside of [$]definitions (other than locations already defined by the spec obviously, e.g. under properties), and that implementations MAY treat any schema that is defined in a nonstandard location as equivalent to {}?

The particular use-case I'm thinking of is a validation implementation which compiles a schema definition into procedural logic for direct execution against a document. Any circumstance which results in an inbound remote reference to a nonstandard location would necessarily imply lazy compilation, which adds significant implementation complexity and may be highly undesirable - in such cases, this would allow the implementation to ignore inbound references to a nonstandard location.

@handrews
Copy link
Contributor Author

@erayd I don't think we should forbid it (although the thought has actually crossed my mind before, so I get your point here). But there's nothing preventing an implementation from saying "if you only put $ref targets under $definitions, your schema will be pre-compiled and fast, and otherwise it may be slow."

I definitely think that reaching into sub-pieces of other schemas (like referencing a particular property schema) is bad form- factor the subschema out to definitions and have both locations reference it. But that's a linter/best practices thing, not a specification thing.

Also, someone writing an extension vocabulary may come up with a good reason to have another location for schemas.

@awwright
Copy link
Member

"definitions" is basically the same thing as a comment. I don't see a problem with this.

@Anthropic
Copy link
Collaborator

@handrews funny how similar this thread is to what I was discussing with you earlier and I hadn't seen this at that point :)

@handrews handrews changed the title Move "definitions" to core Move "definitions" to core (as "$definitions"?) Nov 29, 2017
@handrews
Copy link
Contributor Author

Sounds like the main question is whether to add the $ prefix or not. @json-schema-org/spec-team ?

I had thought not, but am warming to the idea. It would place $definitions, $id, $ref, and $schema clearly in the same category (while #513 which would move keywords like properties over almost certainly does not need the $ prefix as they are a different sort of keyword and, while important, slightly less fundamental)

@epoberezkin
Copy link
Member

Having it in core makes sense. Not so sure about renaming to $definitions. That means that the references should become "#/$definitions/whatever. To be honest, "#/definitions/whatever was quite long already in many cases I used local IDs:

{
  "properties": {
    "foo": {"$ref": "#foo"}
  },
  "definitions": {
    "foo": {
      "$id": "#foo"
    }
  }
}

In any case I don't like renaming to $definitions because refs will become uglier... It does make sense from the consistency point of view though.

Maybe let's move to core to begin with and think longer about renaming. Unlike other keywords with $, definitions does not have any direct effect on the schema processing, it just provides the location for other schemas. It's the argument not to rename.

@gregsdennis
Copy link
Member

gregsdennis commented Dec 19, 2017

@handrews: I don't think we should forbid it

I agree with this. Technically someone could have a reference like #/else/not. Why someone would so this is beyond me, but it's still a valid reference to a location within the document.

@handrews
Copy link
Contributor Author

Further thoughts on naming: As @epoberezkin definitions is already quite long. Would $defs be acceptable? I'm not sure if there is a stylistic / readability concern over a shortened word. We do have const and enum but in the context of programming those are practically normal words anyway.

Then again, Python uses def for defining functions. Not as long of a pedigree as const or enum but not without precedent.

$defs would shorten references for most people and bring it into the $ naming scheme.

I'm not dead set on the $ still but I do lean that way.

@erayd
Copy link

erayd commented Dec 19, 2017

I like the idea of $defs. It's both concise and obvious.

@erayd
Copy link

erayd commented Dec 19, 2017

If you're worried about obviousness of an abbreviated word, $lib could also be a workable option.

@epoberezkin
Copy link
Member

epoberezkin commented Dec 19, 2017

@handrews to be honest, I don't like the look of "#/$", it looks very bash-like. Given that definitions on their own have no impact on validation, they just mark the location in the schema, I'm not sure why we need to rename anything. Users are free to use whatever they choose, really.

@semanino
Copy link

semanino commented Dec 19, 2017

I'd like to repeat my comment on issue #505 here:

IMHO, as far as definitions and $ref are concerned, the discussion on how it should be modelled comes down to the point that they try to meet two different aspects:

  • aspect one: a kind of "library" of schema building blocks, just like e.g. in programming a library of string functions. This is what definitions implements.
  • aspect two: schemas for real-world applications, which arbitrarily use schema building blocks from said libraries. This is what $ref iplements.

With current $ref and $schema there's no way do differentiate between these two aspects.

Yet, they are somewhat different:

  • a library of schemas will have many named schemas as possible $ref targets whitin root level
  • a "normal" schema simply defines exactly one schema at root level

Basically I agree with @handrews that one should not cross-reference from one schema into others - this results IMHO in an ugly spaghetti thing. Yet, factoring out any and all schema parts, that are used more than once, into a separate file definitely rips apart closely coupled things. I think it's fine to put such building blocks into a "global" location whitin the same schema file - this is what definitions implements.
This is the 3rd aspect modelling should consider.

As a result I'd like to suggest the following for consideration (applicable aspect in square brackets):

  • specification of attribute $schema-library which is only allowed on a file's root level [1]
  • it MUST have a [$]def[inition]s member [1]
  • MUST NOT have a type member, i.e. not define a schema itself [1]
  • therefore, references to such a file MUST have a fragment, i.e. something after the # [1]
  • attributes $schema-library and $schema are mutually exclusive [2]
  • generally deny $ref to a $schema file [3]

Pros:

  • each part which is to be used as a building block across multiple schema files must be put into a library, which drives reuseability and impedes spaghetti style
  • schemas still can define "local-only" reusable parts to keep them concise, but these can not be addressed from outside

Cons:

  • the number of schema definition files will slightly increase

Effects on implementation I can't assess because I'm not familiar with it.

@Relequestual
Copy link
Member

Relequestual commented Dec 21, 2017

@semanino Please don't copy paste walls of text which are asking for things not about this issue. Please keep on topic where possible, and reference your comment using a link rather than pasting. Please edit your comment to reflect this. I can see it's slightly different.

@Relequestual
Copy link
Member

Decision:

  • Move definitions to core
  • Rename definitions to $defs

Renaming to shorthand fits with $refs.

@awwright
Copy link
Member

I'm a little wary of renaming things if we don't have to. We could keep "definitions" in validation, so that it still exists in that form.

I think this is more impactful than "$id" since this seems to explect people to change their URIs. And of course, Cool URIs Don't Change.

@handrews
Copy link
Contributor Author

@awwright it's more of a recommendation than a requirement. I think it would go something like this:

  • Implementations/vocabularies MUST NOT define other semantics for $defs
  • Due to historical recommendations, they SHOULD NOT define other semantics for definitions
  • It is RECOMMENDED that new schemas use $defs, but existing schemas MAY continue with definitions (or any non-reserved keyword) and SHOULD NOT change the keyword if other schema documents depend on the URI

Or something like that. We definitely want to avoid the appearance of telling people to reorganize everything Just Because.

I must confess, I hate typing definitions all the time. It makes lines too long and I always misspell it (definitOIns) :-P

@handrews handrews changed the title Move "definitions" to core (as "$definitions"?) Move "definitions" to core (as "$defs"?) Dec 22, 2017
@handrews
Copy link
Contributor Author

This was done as PR #570, but I forgot to close the issue at the time.

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 core Priority: Medium validation
Projects
None yet
Development

No branches or pull requests

8 participants