red888
red888

Reputation: 31662

JSON schema recursion doesn't seem to properly validate

I'm going through the docs to try and figure out how loops work so I can validate every object of an array of objects match the schema.

It seems like recursion is what I want but the example given doesn't work: https://json-schema.org/understanding-json-schema/structuring.html

I'm trying to validate that example but it's always "valid". I tried changing all the field names in the JSON and it doesn't matter:

enter image description here

I'm not sure what's happening. For this example how would I validate every child matches the person schema (without statically writing out each one in the schema).

For example, I want to valid this JSON. there could be any number of objects under toplevel and any number of objects under "objectsList". I want to make sure every object under "objectsList" has the right field names and types (again without hard coding the entire thing in the schema):

{
  "toplevel": {
    "objectOne": {
      "objectsList": [
        {
          "field1": 1231,
          "field2": "sekfjlskjflsdf",
          "field3": ["ssss","eeee"],
        },
        {
          "field1": 11,
          "field2": "sef",
          "field3": ["eeee","qqqq"],
        },
        {
          "field1": 1231,
          "field2": "wwwww",
          "field3": ["sisjflkssss","esdfsdeee"],
        },
      ]
    },
    "objectTwo": {
      "objectsList": [
        {
          "field1": 99999,
          "field2": "yuyuyuyuyu",
          "field3": ["ssssuuu","eeeeeee"],
        },
        {
          "field1": 221,
          "field2": "vesdlkfjssef",
          "field3": ["ewerweeee","ddddq"],
        },
      ]
    },
  }
}

Upvotes: 0

Views: 3033

Answers (2)

Carsten
Carsten

Reputation: 2147

What's wrong?

The problem here is not the recursion – your schema looks good.

The underlying issue is the same as here: https://stackoverflow.com/a/61038256/5127499

JSON Schema is designed for extensibility. That means it allows any kind of additional properties to be added as long as they are not conflicting with the known/expected keywords.

Solution

The solution here is to add "additionalProperties": false in your "person" (from the screenshot) and top-level schema to prevent those incorrect objects to be accepted. Same goes for your second example: in any definitions of "type": "object" you'd have to add "additionalProperties": false if you don't want to allow these extraneous properties to be defined.

Alternatively, you can declare your expected properties as required to ensure that at least those are present.


Why?

As per json-schema.org/understanding-json-schema (emphasis mine):

The additionalProperties keyword is used to control the handling of extra stuff, that is, properties whose names are not listed in the properties keyword. By default any additional properties are allowed.

The additionalProperties keyword may be either a boolean or an object. If additionalProperties is a boolean and set to false, no additional properties will be allowed.

Upvotes: 1

gregsdennis
gregsdennis

Reputation: 8428

To address the screenshot you posted and why the instance passes:

  1. The schema is looking to find a person property, but that property doesn't exist.
  2. The schema does not declare that person is required.
  3. The schema does not declare requirements on undefined properties, so it will always accept the personsdfsd property with whatever value is in it, without checking it further.

So in short, your JSON data is bad and your schema doesn't have any protections against that.

Other than that, your schema looks good. It should validate that items in the children property match the person definition's subschema.

Upvotes: 0

Related Questions