Skip to content

Remove the additionalProperties and additionalItems keywords #373

Closed
@jdesrosiers

Description

@jdesrosiers

JSON Schema validation has some interesting architectural properties. One of those properties is that keyword validations are stateless. They have no dependency on the results of the validation of any other keyword. This means keywords can be evaluated in any order, or even in parallel.

There are two exceptions to this rule: additionalProperties and additionalItems. additionalProperties causes all kinds of problems and confusion when schema authors compose schemas. "additionalProperties": false is used to disallow undefined properties (usually to detect typos), but it also makes it impossible to extend that schema using allOf. This is why I always recommend that additionalProperties not be used and that programs ignore undefined properties instead.

I think the only reason additionalItems isn't similarly notorious is because it is rarely used. Fundamentally, it has the same problems.

I'm not sure if the architectural drift is the reason additionalProperties and additionalItems are problematic or if the problem is intrinsic in what they are trying to do. But, I don't think we should be tacking on additional functionally to solve the problems that additionalProperties causes. Instead, we need to get rid of the cause of the problem and find a way to address the need of detecting typos in a way that doesn't violate the core architecture of JSON Schema. Until we have a good solution, I think it's fine to leave it up to the individual implementations to solve as they see fit. For example, json-schema-validator reports undefined properties as warnings. This seems like a perfectly good solution for most cases. It provides feedback to catch the kind of errors additionalProperties is being used to detect without restricting the composablity of schemas.

I don't think we end up loosing anything by allowing validators to give feedback about undefined properties. However, additionalProperties is also used for another purpose. It is used to describe an object with arbitrary keys whose values must all conform to the same schema. It is possible to describe this with patternProperties using .* as a key. What wouldn't be possible anymore is mixing these arbitrarily-named properties with named properties. I'm ok with that. I don't think it's a good idea to mix those things anyway. It seems a small thing to loose to get rid of something so problematic.

In case it's not clear what I mean ...

{
  "type": "object",
  "properties": {
    "foo": { "type": "string" },
    "bar": { "type": "string" },
    "extraStuff": {
      "type": "object",
      "patternProperties": {
        ".*": { "type": "integer" }
      }
    }
  }
}

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions