Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use object property keys as enum in JSON schema

I'm trying to validate a JSON file using JSON Schema, in order to find cases of "broken references". Essentially my file consists of items and groups, with each item belonging to a single group referenced by the groups property key, like so:

{
    "items": {
        "banana": {
            "name": "Banana",
            "group": "fruits"
        },
        "apple": {
            "name": "Apple",
            "group": "fruits"
        },
        "carrot": {
            "name": "Carrot",
            "group": "vegetables"
        },
        "potato": {
            "name": "Potato",
            "group": "vegetables"
        },
        "cheese": {
            "name": "Cheese",
            "group": "dairy"
        }
    },
    "groups": {
        "fruits": {
            "name": "Fruits"
        },
        "vegetables": {
            "name": "Vegetables"
        }
    }
}

In the example above the item cheese is to be considered invalid, as there are no dairy property in the groups object. I've tried to validate this using the following schema:

{
    "$schema": "http://json-schema.org/draft-06/schema#",
    "title": "Food",
    "id": "food",
    "type": "object",
    "properties": {
        "items": {
            "type": "object",
            "patternProperties": {
                "^[A-Za-z0-9-_.:=]+$": {
                    "properties": {
                        "name": {
                            "type": "string",
                            "pattern": "^[A-Za-z- ]+$"
                        },
                        "group": {
                            "pattern": "^[a-z]+$",
                            "enum": {
                                "$data": "/groups"
                            }
                        }
                    }
                }
            }
        },
        "groups": {
            "type": "object",
            "patternProperties": {
                "^[A-Za-z0-9-_]+$": {
                    "properties": {
                        "name": {
                            "type": "string",
                            "pattern": "^[A-Za-z- ]+$"
                        }
                    }
                }
            }
        }
    },
    "additionalProperties": false
}

This has the effect that the enum for group is populated by the property values in groups, but what I want to do is use the property keys defined in groups.

If I add a property like e.g. groupIds and let that be an array of all property keys found in groups and specify the enum as "$data": "/groupIds" it does work, so I take this to be a JSON pointer issue.

The enum keyword in JSON Schema is defined as:

The value of this keyword MUST be an array. This array SHOULD have at least one element. Elements in the array SHOULD be unique.

So if I could only get JSON pointer to reference an object's keys rather than its values I guess the enum validation would just work. I'm thinking something like "$data": "/groups/.keys", "$data": "/groups/$keys" or similar, but haven't found it while googling or reading the spec. Is there such a thing or has it ever been proposed?

like image 909
Simon Avatar asked Nov 23 '17 11:11

Simon


1 Answers

There is no such thing. It’s very close to general expressions inside JSON and it may have some use cases, but there is no such specification.

like image 192
esp Avatar answered Sep 19 '22 10:09

esp