Liquid XML Studio 2019
Schema Dependency
JSON Schema Editor > Graphical Notation Overview > Dependency Container > Schema Dependency
Draft 04 Draft 06 Draft 07

A schema dependency has a named property and a sub schema. If the named property exists, then the schema is applied to the containing object, and must validate.

 

There is no requirement that any of the property names match a property definition (as they could match against Pattern Property or Additional Property nodes).

Example 1

Example
Copy Code
{
    "$schema": "http://json-schema.org/draft-04/schema#",
    "type": "object",
    "title": "My schema",
    "additionalProperties": true,
    "properties": {
        "a": { "type": "string" },
        "b": { "type": "string" }
    },
    "dependencies": {
        "a": {
            "type": "object",
            "properties": {
                "x": { "type": "number" }
            },
            "required": [ "x" ]
        }
    }
}

In this example if the property 'a' is present then the contained schema must also validate the containing instance object.

Valid
Copy Code
{
    "a":"String",
    "x":4
}
Invalid
Copy Code
{
    "a":"String"
}

As this validation effectively uses 2 schemas to validate the same instance object the 2 schemas must 'overlap'.

In other words the properties defined by the core schema must also be allowable by the dependency schema and visa versa.

This is easiest to do by ensuring both schemas contain an Additional Properties node (but can be done with property or PatternProperty nodes.

 

Example 2 - Restricting Existing Types

Schema dependencies can also be used to further constrain existing property definitions.

Example
Copy Code
{
    "$schema": "http://json-schema.org/draft-04/schema#",
    "type": "object",
    "title": "My schema",
    "additionalProperties": false,
    "properties": {
        "a": { "type": "string" },
        "b": {
            "type": "string",
            "minLength": 3
        }
    },
    "dependencies": {
        "a": {
            "type": "object",
            "properties": {
                "b": {
                    "type": "string",
                    "maxLength": 4
                }
            }
        }
    }
}

In this example property 'a' is optional and can contain a string of any length, and property 'b' is optional, but if present must contain a string of 3 or more chars.

However, because of the dependency rule, if the property 'a' is present then additional rules are applied to property 'b' (if present).

The additional rule in the dependency ensure that  'b' can contain any string with a max length of 4.

The constraints of the core and dependency schema are both applied ensuring if b is present it is s string of 3-4 chars.

Valid
Copy Code
{    "a":"String with no restrictions"    }

{    "b":"Long String - Which is Valid as 'a' is not present"    }

{   
     "a":"String with no restrictions",
     "b":"ABC"
}
Invalid
Copy Code
{    "b":"A"    }   // To Short

{    
     "a":"String with no restrictions",
     "b":"ABCDE"    // To Long as dependency rules are applied as 'a' is present.
}     

 

Example 3 - Excluding Existing Properties

Schema dependencies can also be used to remove existing properties.

The logic and implementation for this are not intuitive, so its best avoided if possible!
But you do see it in a number of production schemas.

Example
Copy Code
{
    "$schema": "http://json-schema.org/draft-04/schema#",
    "type": "object",
    "title": "My schema",
    "additionalProperties": false,
    "properties": {
        "a": { "type": "string" },
        "b": { "type": "string" }
    },
    "dependencies": {
        "a": {
            "type": "object",
            "not": { "required": [ "b" ] }
        }
    }
}
If your not familiar with the 'not' node, then its probably a good idea to read through that topic first.

In this example property 'a' is optional and can contain a string of any length, and property 'b' is optional and contain a string of any length.

However, because of the dependency rule, if the property 'a' is present the following additional rules apply :

The object must validate against the schema in the dependency, which contains:

A Properties Collection which contains an additional properties node (this allows any properties so has no effect on the validation).

A Not schema (which is not allowed to validate against the containing instance object), this contains:

A required property 'b'  and an additional properties node (so this will validate if the property 'b' is present).

 

The negative logic here makes this somewhat unintuitive, but basically reading backwards.

Valid
Copy Code
{                    }

{    "a":"String"    }

{    "b":"String"    } 
Invalid
Copy Code
{
    "a":"String",
    "b":"String"
}