ban unknown properties mode (v5 proposal) - sgpinkus/json-schema GitHub Wiki

THIS WIKI IS OBSOLETE. PLEASE SEE THE NEW JSON-SCHEMA-ORG/JSON-SCHEMA-SPEC REPOSITORY.



Proposed keywords

None - this would be described in a separate heading, titled something like "Alternative validation modes".

Purpose

There have been many attempts to write schemas (or propose/modify keywords) in order to ban undocumented properties from a schema while still allowing these "undocumented" properties to be given definitions by other schemas that inherit the basic standard.

This proposal would describe an "alternative validation mode" called "Ban Unknown Properties". This would be completely optional, and probably implemented as a flag or config option in validators that support it.

If included in the standard, it is likely that a completely optional and clearly separate set of tests would be written that tested behaviour for "ban additional properties" mode.

Behaviour

Validation is initially calculated as normal. After validation, the data is scanned to make sure that all properties used are described in at least one schema.

anyOf

Property definitions are applicable from any sub-schema in anyOf for which the data is valid. That is, for the schema {"anyOf": [A, B]}, then the property definitions from schema A are only applicable when the data is actually valid according to schema A

oneOf

Property collection for oneOf is the same as for anyOf. The only difference is that because of the way oneOf works, if validation succeeds then exactly one sub-schema will be valid, so exactly one set of property definitions will be applied.

not

not clauses are ignored, and any property definitions inside them do not count.

additionalProperties

If additionalProperties is specified in the schema, then all properties for that data are considered "known". This applies for {"additionalProperties": true} as well.

Examples

Simple case
{
    "type": "object",
    "properties": {
        "propA": {},
        "propB": {}
    }
}

Known properties are "propA" and "propB"

not
{
    "not": {
        "type": "object",
        "properties": {
            "propA": {},
            "propB": {}
        }
    }
}

This schema defines no known properties.

oneOf
{
    "type": "object",
    "oneOf": [
        {
            "properties": {
                "propA": {"type": "string"}
            }
        },
        {
            "properties": {
                "propB": {"type": "number"}
            }
        }
    ]
}

For the data: {"propA": "test", "propB": "test"}, then "propA" is the only known property - the definition for "propB" is not used, because the data does not match the second sub-schema.

For the data: {"propA": 5, "propB": 5}, then "propB" is the only known property - the definition for "propA" is not used, because the data does not match the first sub-schema.

Calculate separately for different instances
{
    "type": "array",
    "items": {
        "type": "object",
        "oneOf": [
            {
                "properties": {
                    "propA": {"type": "string"}
                }
            },
            {
                "properties": {
                    "propB": {"type": "number"}
                }
            }
        ]
    }
}

For the following data, there are no unknown properties:

[
    {
        "propA": "test"
    },
    {
        "propB": 5
    }
]

However, for this data, there is an unknown property at /0/propB ("propB" in the first item). Even though "propB" is defined for the second item, its definition does not apply to the first one.

[
    {
        "propA": "test",
        "propB": "test"
    },
    {
        "propB": 5
    }
]

Concerns

Default behaviour

It must be made abundantly clear that this should not be the default mode for validators. If your default mode fails the test suite, then we would not list you as "v5-compliant" on the web-site.

Implementation

Can be relatively straight-forward. One validator (tv4) has already implemented this feature.

Flexibility

This mode does not allow unknown properties in some schemas but not others. However, this can be counteracted by specifying additionalProperties:

{
    "type": "object",
    "properties": {
        "propA": {
            "type": "object",
            ...
        },
        "propB": {
            "type": "object",
            "additionalProperties": true,
            ...
        }
    }
}

In that example, even when validated under "ban additional properties" mode, "propB" would be allowed arbitrary extra/undocumented properties, because they are covered by "additionalProperties": true.

(An actual schema for additionalProperties would also work.)

⚠️ **GitHub.com Fallback** ⚠️