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

Wild idea for vocabs #1523

Open
gregsdennis opened this issue Jun 20, 2024 · 2 comments
Open

Wild idea for vocabs #1523

gregsdennis opened this issue Jun 20, 2024 · 2 comments

Comments

@gregsdennis
Copy link
Member

I had a weird-but-maybe-good idea about how vocabularies could work.

C# has the using directive which declares a namespace containing types that are used throughout the file.

Javascript has the import directive, which kinda does the same thing. The cool thing about imports, though, is you can pull in specific exports from the target and you can rename the exports to something else.

So what if a vocab declaration did the same thing? What if the value inside the $vocabulary keyword was expanded to support more than a boolean?

My idea was for it to support an object that has two properties:

  • using would be an array of the keywords from the vocab that could be used in a schema
  • remap would be an object of strings mapping vocabulary keywords to new keywords

It could look like this:

{
  "$vocabulary": {
    // takes only anyOf, allOf, and oneOf, but remaps oneOf to takeOne
    "https://json-schema.org/draft/next/vocab/applicator": {
      "using": ["anyOf", "allOf"],
      "remap": {
        "oneOf": "takeOne"
      }
    },
    // takes all keywords as they are
    "https://json-schema.org/draft/next/vocab/validation": true,
    // takes all keywords, but remaps title to name
    "https://json-schema.org/draft/next/vocab/meta-data": {
      "remap": {
        "title": "name"
      }
    },
    // ...
  }
}

(The word "import" has a history with JSON Schema of being the keyword of choice for people trying to recommend a way to support polymorphism. Also OpenAPI 4 is looking to define it. So it's probably best we stay away from that. I've used "using" here, but I'm open to other suggestions.)

If the value is true, then it takes the vocab as-is. If using is missing, it takes all of the keywords.

This allows users to take only specific keywords or to remap keywords, which handles "json schema but in spanish" and provides a way to handle keyword name conflicts.

A false value could still mean that the vocab is optional, but implementations can only refuse to process the schema if it actually uses the keywords from that unknown vocab. Basically, the implementation's saying, "Hey, I don't know this vocab. Hope you don't use keywords from it..." The use case for this would be having a single meta-schema to describe multiple schemas, where only some of those schemas use the optional keywords. (Seems like a stretch use case when you could just have two meta-schemas, one with the vocab and one without it.)

This renders all current usages of $vocabulary still valid, so it's backward compatible!

This might be something we could consider putting into place until we develop $dialect or something else that's better.

There are two catches here:

  1. Renaming keywords like this requires a meta-analysis prior to (or just before but part of) evaluation, which is a behavior that JSON Schema doesn't have yet
  2. Meta-schema evaluation is going to be difficult. We'd have to require that meta-schema evaluating means reversing the keyword mappings in order to make the property names align with what's in properties. This further makes meta-schema evaluation a special task, separate from merely evaluating the schema like an instance.

Also, since the core vocab is implied anyway (it's a current requirement), I'd add a requirement that it can't be listed here to prevent its keywords from being remapped.

(Lastly, to be clear, I'm offering this option knowing full well that it would likely be a pain to implement in my architecture.)

@gregsdennis gregsdennis added the proposal Initial discussion of a new idea. A project will be created once a proposal document is created. label Jun 20, 2024
@gregsdennis
Copy link
Member Author

Linking to #1510 for future reference.

@jdesrosiers
Copy link
Member

I like the general idea. It's similar to something I've proposed in the past except that I decouple keywords from vocabularies more (without eliminating the concept of vocabularies). But, this variation is interesting because it's backwards compatible with what we currently have!

Meta-schema evaluation is going to be difficult.

I had the same issue with my proposal. What I ended up with was that the concept of a meta-schema kinda goes away. JSON Schema becomes too dynamic for a single meta-schema to make sense. Instead, each keyword has it's own schema and I would validate each keyword individually as I compile the schema. That ends up being fairly simple to implement.

My biggest concern with vocabularies is that I strongly believe that we need to give users the ability to declare the extension keywords they want to use directly in their schema. They shouldn't have to write a custom meta-schema. Whatever we end up with needs to support that kind of use. This proposal doesn't, but we could use this kind of approach in something that does.

@gregsdennis gregsdennis removed the proposal Initial discussion of a new idea. A project will be created once a proposal document is created. label Jul 16, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Development

No branches or pull requests

2 participants