JSON Schema v4 "required" in nested object

Kevin picture Kevin · Jul 28, 2015 · Viewed 10.3k times · Source

I tried searching, but I'm not quite sure how to put this in words! The point of confusion is how "required" works in JSON schema v4 when there are nested key values with the same name.

For example, this schema:

{
    "Root": {
        "type": ["array", "null"],
        "items": {
            "type": "object",
            "properties": {
                "LevelOne": {
                    "required": ["id", "name", "LevelOneRepeat"],
                    "id": {
                        "type": "string"
                        },
                    "name": {
                        "type": "string"
                        },
                    "LevelOneRepeat": {
                        "type": ["array", "null"],
                        "items": {
                            "type": "object",
                            "properties": {
                                "required": ["id", "name"],
                                "id": {
                                    "type": "string"
                                    },
                                "name": {
                                    "type": "string"
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}

Inside LevelOne, I have a required for "id", "name", and "LevelOneRepeat". However, inside LevelOneRepeat, I also have a required for "id" and "name".

Does required only check for elements in the same level, or also all child elements? Do I need to include the required inside LevelOneRepeat if the key values required (same name) are already listed in the level above?

I tested my JSON with my schema, but I might've messed up my code somewhere as no required are working anymore.

Answer

Jason Desrosiers picture Jason Desrosiers · Jul 28, 2015

You have a couple of issues with your schema that is probably what has led to your confusion about how required works.

Here is the corrected schema.

{
    "type": ["array", "null"],
    "items": {
        "type": "object",
        "properties": {
            "LevelOne": {
                "type": "object",
                "properties": {
                    "id": { "type": "string" },
                    "name": { "type": "string" },
                    "LevelOneRepeat": {
                        "type": ["array", "null"],
                        "items": {
                            "type": "object",
                            "properties": {
                                "id": { "type": "string" },
                                "name": { "type": "string" }
                            },
                            "required": ["id", "name"]
                        }
                    }
                },
                "required": ["id", "name", "LevelOneRepeat"],
            }
        }
    }
}

The first problem is with the way you define nested objects. The value of each property must be a schema. See how I changed the LevelOne definition to see how to correctly define a nested object.

The second problem is that have the required keyword in the wrong place. It should be on the same level as the properties keyword, not nested within the properties object. This is why your required constraints weren't working. See how I changed the LevelOne and LevelOneRepeat definitions.

Once you fix these problems, hopefully it should be more clear that the required keyword only applies to the schema it is defined in. It does not apply to any parent or child schema.