Skip to content

Dynamic enum values based on other values in document #331

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
colbywhite opened this issue Jun 11, 2017 · 8 comments
Closed

Dynamic enum values based on other values in document #331

colbywhite opened this issue Jun 11, 2017 · 8 comments
Milestone

Comments

@colbywhite
Copy link

colbywhite commented Jun 11, 2017

Consider the following correct JSON:

{
  "things": [
    { "name": "A", "someOtherProp": 3 },
    { "name": "B", "someOtherProp": 9 }
   ],
  "schedule": ["A", "B", "B", "A"]
}

And consider the following JSON that one might want to be incorrect:

{
  "things": [
    { "name": "A", "someOtherProp": 3 },
    { "name": "B", "someOtherProp": 9 }
   ],
  "schedule": ["A", "B", "B", "A", "C"]
}

As far as I can tell - and I very well may just not be seeing it - but I don't think the current spec allows me to define that all items of the schedule property must be also present in things[*].name. The "C" in the second JSON should be invalid since it doesn't appear in things[*].name. I don't think you can use oneOf or enum in this scenario since you don't know beforehand what things[*].name are. They can be anything the user decides, in this case any string.

To further illustrate the point, the following schema validates both JSONs.

{
  "schema": "http://json-schema.org/schema#",
  "type": "object",
  "properties": {
    "things": {
      "type": "array",
      "items": {
        "type": "object",
        "required": [ "name" ],
        "properties": {
          "name": { "type": "string" }
        }
      }
    },
    "schedule": {
      "type": "array",
      "items": { "type": "string" }
    }
  }
}

Assuming I'm not missing anything and the current spec doesn't support this, would this be a worthwhile addition? Or is it outside the scope of this? Is this related to the $data discussion that appears to be happening?

For the sake of brainstorming what that would look like using $ref & oneOf (which might not be the best option):

    "schedule": {
      "type": "array",
      "items": { 
        "type": "string", 
        "oneOf": "$ref/things/*/name"
      }
    }
@handrews
Copy link
Contributor

This is related to $data, so I'll tag it as such, but it's more complex. $data lets you point to one other location in the instance and use its value (and in some variations, its property name or array index) as a dynamic value for some other keyword. You want to reference a set of object property values sliced across an array which requires some sort of pointer template wildcarding which is not something that's come up AFAIK. Although I haven't gone and read all of the others.

At some point, it is better to handle more complex relationships in application logic, perhaps keyed to extension keywords of your own, than to get schema validation to do it. At first glance, I would put this proposal in that category. But that's just an initial impression.

@handrews handrews added the $data label Jun 14, 2017
@handrews handrews added this to the draft-07 (wright-*-02) milestone Jun 14, 2017
@colbywhite
Copy link
Author

At some point, it is better to handle more complex relationships in application logic

I was going back-and-forth on if this scenario qualified as such. I'm not sure which way it should land. On one hand, this is a flat file and dynamic stuff kind of goes out the scope of a flat file. But on the other hand, in this scenario, all the validation will come from the file itself. In the above example, validation doesn't require any app-specific state or anything like that. All the inputs to the validation are in the file itself. So why not allow the file to validate itself so to speak? I don't know the right answer to that.

The fact that there is contemplation of the $data paradigm implies you are already going down the path of allowing for dynamic values, although this scenario is a bit more difficult. Is that a fair summary of where you're at? If you're going down that path, than this scenario seems like a logical extension in the future. (And I wouldn't mind helping you get there, although I wouldn't know where to start.)

@handrews
Copy link
Contributor

The fact that there is contemplation of the $data paradigm implies you are already going down the path of allowing for dynamic values

Actually that is a hotly contested decision. It's one of the two big decisions we need to sort out for draft-07:

  • What sort of re-use mechanisms, if any, do we need beyond anyOf/oneOf/allOf?
  • Is the $data paradigm in-scope or not?

Once we've made those decisions, figuring out how to implement them and how far to go (e.g. do we add this or not) becomes much simpler.

@handrews
Copy link
Contributor

"$data" will not be decided for the next draft, so I'm moving this out as well.

@gmile
Copy link

gmile commented Apr 13, 2018

@handrews from looking at current (?) draft, $data is missing. Was it superseded by something else?

Our use-case is that we need to perform enum validation in the schema. Every time an instance is validated against a schema, we pull the enum values from database, and then compile the schema. We compile the schema for every request, which is a huge overhead (of course this can be worked around by caching, but it is sub-optimal).

@handrews
Copy link
Contributor

@gmile $data has never been a part of the spec. One implementation supports it as a custom extension, but there has never yet been consensus that it is the correct approach. There are some alternatives, which you can find by clicking on the $data label to see all of the associated issues. This will likely be the focus of draft-09 (we are currently working on draft-08, which is more than full at this point).

@gmile
Copy link

gmile commented Apr 13, 2018

@handrews noted on $data, thank you. Looking forward to following discussions around it in draft-09! :)

@handrews
Copy link
Contributor

This sort of request is being comprehensively tracked at #855, where we have consolidated several related ideas.

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

3 participants