Description
Definition
The value of this keyword is a JSON-schema. The keyword only applies to objects. If the instance is not an object, validation succeeds. For the instance to be valid all property names of the object should be valid according to this schema. Possible variant: only apply it to property names not explicitly mentioned in properties
keyword - there are pros and cons for it.
Motivation
Generally the current spec is more suited for the data stored in values with static keys. The only exception to that is patternProperties
.
There are two disadvantages of patternProperties:
- You cannot define any other restriction apart from, well, pattern
- Even if pattern is sufficient but you need to use the same property names pattern in multiple objects (but with different schemas for values, so you can't use $ref), you have to repeat the same pattern over and over again. It is difficult to maintain and to ensure they are the same.
propertyNames
addresses both issues. So instead of having:
{
"patternProperties": {
"^(\\d{1,3}\\.){3}(\\d{1,3})$": { "$ref": "hostData.json" }
},
"additionalProperties": false
}
you can have:
{
"propertyNames": { "$ref": "#/definitions/host" },
"additionalProperties": { "$ref": "hostData.json" },
"definitions": {
"host": { "pattern": "^(\\d{1,3}\\.){3}(\\d{1,3})$" }
}
}
or even
{
"propertyNames": { "$ref": "#/definitions/host" },
"additionalProperties": { "$ref": "hostData.json" },
"definitions": {
"host": {
"anyOf": [
{ "format": "hostname" },
{ "format": "ipv4" }
]
}
}
}
You can see how using propertyNames
allows to have the schema for property names that is:
- more advanced than simple pattern matching
- can be reused and updated in a single place.
We use this keyword a lot, it is defined as a custom keyword for Ajv. It seems to be so useful and simple that maybe it's worth considering adding it to the spec.