json-schema-org / json-schema-spec

The JSON Schema specification
http://json-schema.org/
Other
3.69k stars 260 forks source link

Is it possible to get a list of object keys using JSON pointers? #1378

Open adrfantini opened 1 year ago

adrfantini commented 1 year ago

Is there any way to obtain the list of keys of an object using JSON pointers?

I've found an old issue regarding this, but no solution yet.

jdesrosiers commented 1 year ago

No. Something like that would be out of scope for JSON Pointer. JSON Pointer is a very simple tool that does one thing, pointing to a location in a JSON document. I suggest looking into JSON querying tool such as JSONPath, JMESPath, JSONata, or jq. I'm not up-to-speed on the feature set of any of those tools, but the feature you're looking for should be in scope for tools like those.

gregsdennis commented 1 year ago

What you could do is take off the last segment of the pointer and resolve that. Then you just need to access the value you get to iterate over the keys.

adrfantini commented 1 year ago

My bad. I somehow pasted the issue title instead of the link :facepalm:

The correct old issue link is: https://github.com/json-schema/json-schema/issues/245

What you could do is take off the last segment of the pointer and resolve that. Then you just need to access the value you get to iterate over the keys.

Can this be done programmatically with any of the JSON validators that use JSON schema, such as ajv or jsonschema? Unless I misunderstood how JSON pointers work (just started learning JSON schema last week), there's no way to do that.

A possible usecase would be a JSON with the following schema:

{
  "items": ["pen", "pineapple", "pencil"]
  "itemConf": {
    "pen": {"hasInk": true},
    "pineapple": {"hasInk": false},
    "pencil": {"hasInk": false}
  }
}

In this case you want to validate that the object keys present in itemConf are in fact listed in items, and viceversa. This is a stupid example of course, but stuff like this happens all the time!

jdesrosiers commented 1 year ago

That is certainly something that people often want to do and JSON Schema can't express, but I don't see how a JSON Pointer returning a list of object keys solves that problem.

adrfantini commented 1 year ago

That is certainly something that people often want to do and JSON Schema can't express, but I don't see how a JSON Pointer returning a list of object keys solves that problem.

Naively I would think to use those keys as enum condition for the strings in items.

jdesrosiers commented 1 year ago

I see what you're saying. You'd like to do something like this.

{
  "type": "object",
  "properties": {
    "items": {
      "enum": { "$ref": "$data$#/itemConf$keys$" }
    }
  }
}

I made up some syntax to fill in the gaps, but I think you get the idea. The first problem, of course, is that there isn't a way to query for keys. Here I used the $keys$ postfix as an example. The second problem is that you need to reference the data being referenced, rather than a schema. There's no way to do that because the data doesn't inherently have an identifier that can be reference. I used the $data$ prefix to show this missing piece. The third problem is that a JSON Schema can only use a reference where a schema is expected, so it wouldn't be allowed as a value for enum.

Even if we do come up with a solution for the second and third problem, I wouldn't want to expand JSON Pointer with querying features. I'd rather introduce a way to use an actual query language like JSON Path for cases like this.

gregsdennis commented 1 year ago

I'd rather introduce a way to use an actual query language like JSON Path for cases like this.

We haven't put that in yet. Actually we've explicitly decided against it for now.

See https://github.com/ietf-wg-jsonpath/draft-ietf-jsonpath-base/issues/156.

I also would like to identify the use case.

adrfantini commented 1 year ago

I'm out of my depth with the technicalities to be fair.

To me it looks something that'd be very handy very often. In fact, in a week working on-and-off with JSON schema, I found not one, not two but three JSONs that would benefit from a feature such as this, among those I'd like to validate. Yes, they are not very well thought out JSONs, to be fair, but still.

I can come up with more examples if my code above and the mock implementation provided by @jdesrosiers are not clear enough.

jdesrosiers commented 1 year ago

It's not a matter of whether or not we think it will be useful. I think it's pretty clear that it is. It's just a matter of someone proposing a workable solution and championing getting it added to the spec. I'd definitely support it if a good approach is found.