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

Suggestion: String JSON Schemas as shortcut for $ref #1078

Open
moander opened this issue Feb 27, 2021 · 13 comments
Open

Suggestion: String JSON Schemas as shortcut for $ref #1078

moander opened this issue Feb 27, 2021 · 13 comments
Labels
core referencing Anything that might be replaced with the outcome of the work in the referencing repo Type: Enhancement

Comments

@moander
Copy link

moander commented Feb 27, 2021

A schema is either an object or a boolean. What if there was a third option (string) that is a shortcut for $ref?

So instead of models like this

{
  "$id": "https://example.com/schemas/my-model.json",
  "properties": {
    "foo": {
      "$ref": "shared-type1.json"
    },
    "bar": {
      "$ref": "shared-type2.json"
    },
    "jau":{
      "type": "string"
    },
    "hei":{
      "type": "string"
    }
  }
}

You get

{
  "$id": "https://example.com/schemas/my-model.json",
  "properties": {
    "foo": "shared-type1.json",
    "bar": "shared-type2.json",
    "jau": "#string",
    "hei": "#string"
  },
}
@gregsdennis
Copy link
Member

Thanks for the suggestion! I think it's a really interesting idea, and it shouldn't be very hard to implement.

@Relequestual
Copy link
Member

This would have complex consequences.

For example, what are the annotation results now?
How does such a change impact the additionalProperties, patternProperties, and unevaluatedProperties chain?

I'm generally against making these complex things more complex and potentially more confusing.

@moander
Copy link
Author

moander commented Feb 28, 2021

This would have complex consequences.

My thought was that the complexity and consequences of having such shortcuts already is taken care of by implementors because of the boolean schema. Can the same rules and arguments that lead to the boolean schema be used to support this feature or will it have different impact on things like additionalProperties and so on?

@gregsdennis
Copy link
Member

gregsdennis commented Feb 28, 2021

So the boolean schemas don't have any annotations or provide any assertions. As a result, they have no impact on these other keywords, which rely upon those annotation and assertions.

However, an implicit $ref would have the results of the references schemas, so it must be considered how those results are incorporated into the mix.

Another point is output. Currently there are two location indicators in the output format, schemaLocation which shows the relative path to the keyword being processed and absoluteSchemaLocation which gives the direct, fixed path. Having an implicit $ref would affect the relative path (schemaLocation) because $ref is currently part of the path to indicate that a jump from one location to another was made. However if $ref is implied, is it no longer in the output? If not, it's harder to tell that such a jump was made by looking at the pointer.

@Relequestual
Copy link
Member

I don't want to open this can of worms right now, and we have other issues we DO need to solve.
My personal preference would be to close this issue, but if @gregsdennis really wants, we can keep it open to discuss maybe sometime in the future, but it would probably be "hard no" from me still.

It's not uncommon there seems to be something that could be made simpler or a shortcut added, but it's often it's that way for a reason.

@jdesrosiers
Copy link
Member

This would have complex consequences.

No it doesn't. In fact it fixes some of the complex consequences of allowing $ref to have siblings. I explain in #936 (comment). I could implement this in Hyperjump JSC in just a couple lines of code. Everything would just work exactly like $ref used to work before 2019-09. The worst consequence of this change is people might get confused because schemas would look different than they are used to.

@Relequestual
Copy link
Member

I'd have to read up on what was said, but I can't imagine how this would fix any issues, as it wouldn't be in stead of allowing $ref siblings.

@awwright
Copy link
Member

I've floated this idea before, myself. I don't think we permit strings anywhere that schemas may be found, and I'm not aware of any historical reasons that would conflict.

@jdesrosiers
Copy link
Member

I added support for this in Hyperjump JSC (the engine behind the validator implementation). That would allow someone to create a dialect that supports string references. I'm not providing such a dialect, just the tools to configure a dialect with that functionality.

I did this as a proof of concept. I learned that it is indeed very easy to implement (3 lines of code) and there aren't any hidden complexities as far as I can see.

@notEthan
Copy link
Contributor

I think there is no technical reason that this could not be supported and behave like a schema with only a $ref keyword, but I am against it as it negatively impacts readability. with the $ref keyword, if you don't already know what it is, you can easily learn what $ref means and does (open the spec or the understanding-json-schema and search for "$ref"). a URI with no context is more difficult to make sense of if you are not familiar with all aspects of json-schema.

@handrews handrews added the referencing Anything that might be replaced with the outcome of the work in the referencing repo label Oct 28, 2022
@gregsdennis
Copy link
Member

gregsdennis commented Aug 27, 2023

with the $ref keyword, if you don't already know what it is, you can easily learn what $ref means and does (open the spec or the understanding-json-schema and search for "$ref"). a URI with no context is more difficult to make sense of if you are not familiar with all aspects of json-schema.

I doubt it will cause any more confusion than when we introduced boolean schemas. Basically, we said, "Here's draft 6! And BTW now you can use booleans everywhere you can use a schema: true instead of {} and false instead of { "not": {} }. People seem to have caught on to that pretty easily. This is the same, except we're saying, "Here's the next iteration! And BTW, you can use strings everywhere you can use a schema: it's gotta be a URI and it means { "$ref": "<URI>" }.

Yeah, maybe the learning curve is a bit steeper, but I don't think it's sufficiently steeper to cause worry.

@gregsdennis
Copy link
Member

I think the complexity will come in trying to enforce URIs in the strings. Currently our only mechanism for that is by using format.

However, we use format currently in the definition of $ref, and that's not validated (by default) so maybe it's not an issue.

@gregsdennis
Copy link
Member

FWIW, I was able to implement this in my library in about three minutes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
core referencing Anything that might be replaced with the outcome of the work in the referencing repo Type: Enhancement
Projects
None yet
Development

No branches or pull requests

7 participants