Yuk, upward dependencies can be really unpleaseant. Does the model have to be shaped that way?

Solution

You are on the right track. What you are missing is checking correctly if at least one element of "Fields" array had that "SW Large" : true and then shape the proper dependency.

Since draft-06 it is solved with "contains" keyword. In order to not repeat content, I'd recommend to read following:

JSON Schema: How to check that an array contains at least one object with a property with a given value?

Json Schema: Require a property only when a specific property is present in a deep nested object (very educational!)

https://json-schema.org/understanding-json-schema/reference/array.html

Your schema re-worked below. See the "definitions" section

First of all it's adding "contains" : { schema } to "Fields" definition. I need it as separate schema in order to use it as a condition in logical implication.

"definitions" : {
    "Fields-contains-at-least-1-element-with-SW-Large-true" : {
      "properties": { 
        "Fields" : {
          "contains" : {
            "properties": { 
              "SW Large": { "enum": [true] } 
            },
            "required" : ["SW Large"]
          }
        } 
      },
    }
  },

If you would add it permanently, it might look like:

"Fields" : {
  "type" : "array",
  "contains" : {
    "properties": { 
      "SW Large": { "enum": [true] } 
    },
    "required" : ["SW Large"]
  }
  "items": {...},
}

which translates to "at least one item of "Fields" array must contain object with said property name and said value". Every JSON with "Fields" array that contains no item with "SW Large" : true would fail validation against such schema. And if you reverse the "contains" schema definition like:

"Fields" : {
    "type" : "array",
    "contains" : {
      "not" : {
        "properties": { 
          "SW Large": { "enum": [true] } 
        },
        "required" : ["SW Large"]
      }
    }
    "items": {...},
  }

it would translate to "no item of "Fields" array can contain object with said property name and said value". Every JSON with "Fields" array that contains at least one item with "SW Large" : true would fail validation against such schema.

I don't want any of above to happen. I want to link "Fields/contains" condition with requiring or not requiring the "SW Words" property one level above, hence getting schema excluded to "definitions" section and making a proper use of it.

The "upward-dependency" is defined using that check and proper logical implication with "anyOf" keyword

It doesn't contain at least 1 item with "SW Large" : true OR "SW Words" is required

"definitions" : {
    "upward-dependency" : {
      "anyOf" : [
        { "not" : {"$ref" : "#/definitions/Fields-contains-at-least-1-element-with-SW-Large-true"} },
        { "required" : ["SW Words"] }
      ]
    },
  },

At the level of single item of "Registers" array I've added the "dependencies". Whenever "Fields" item appear in one of "Registers" items, it's been checked if it contains the unfortunate "SW Large" : true and if it does - the "SW Words" becomes required. Voila!

       "items" : {
        "$id": "#/properties/Registers/items
        "type" : "object",
        "properties" : {
          "Fields": {
            "$id": "#/properties/Registers/items/properties/Fields",
            "type": "array",
            "items": {
              "$id": "#/properties/Registers/items/properties/Fields/items",
              "type": "object",
              "propertyNames" : {
                "enum" : [
                  "Name",
                  "SW Large"
                ]                
              },
              "required": [
                "Name"
              ],
              "properties": {
                "Name": {
                  "$id": "#/properties/Registers/items/properties/Fields/items/properties/Name",
                  "type": "string"
                },
                "SW Large": {
                  "$id": "#/properties/Registers/items/properties/Fields/items/properties/SW Large",
                  "type": "boolean"
                }
              }
            }
          }
        },
        "dependencies" : {
          "Fields" : { "$ref" : "#/definitions/upward-dependency" }
        },
      }

I've checked Schema with online validator and added your object to "examples" section.

Full schema:

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "$id": "http://example.com/root.json",
  "type": "object",
  "propertyNames" : {
    "enum" : [
      "Registers"
    ]
  },
  "required": [
    "Registers"
  ],
  "examples" : [
    {
      "Registers": [
        {
          "Name": "device",
          "Address": "100",
          "SW Words": 2,
          "Fields": [
            {
              "Name" : "Product",
              "SW Large" : true
            },
            {
              "Name": "Version"
            }
          ]
        }
      ]
    }
  ],
  "properties": {
    "Registers": {
      "$id": "#/properties/Registers",
      "type": "array",
      "items": {
        "$id": "#/properties/Registers/items",
        "type": "object",
        "propertyNames" : {
          "enum" : [
            "Name",
            "Address",
            "SW Words",
            "Fields"
          ]
        },
        "required": [
          "Name",
          "Address",
          "Fields"
        ],
        "properties": {
          "Name": {
            "$id": "#/properties/Registers/items/properties/Name",
            "type": "string"
          },
          "Address": {
            "$id": "#/properties/Registers/items/properties/Address",
            "type": "string"
          },
          "SW Words": {
            "$id": "#/properties/Sections/items/properties/Blocks/items/properties/SW Words",
            "type": "integer",
            "default": 2,
            "minimum": 2
          },
          "Fields": {
            "$id": "#/properties/Registers/items/properties/Fields",
            "type": "array",
            "items": {
              "$id": "#/properties/Registers/items/properties/Fields/items",
              "type": "object",
              "propertyNames" : {
                "enum" : [
                  "Name",
                  "SW Large"
                ]                
              },
              "required": [
                "Name"
              ],
              "properties": {
                "Name": {
                  "type": "string"
                },
                "SW Large": {
                  "type": "boolean"
                }
              }
            }
          }
        },
        "dependencies" : {
          "Fields" : { "$ref" : "#/definitions/upward-dependency" }
        },
      }
    }
  },
  "definitions" : {
    "upward-dependency" : {
      "anyOf" : [
        { "not" : {"$ref" : "#/definitions/Fields-contains-at-least-1-element-with-SW-Large-true"} },
        { "required" : ["SW Words"] }
      ]
    },
    "Fields-contains-at-least-1-element-with-SW-Large-true" : {
      "properties": { 
        "Fields" : {
          "contains" : {
            "properties": { 
              "SW Large": { "enum": [true] } 
            },
            "required" : ["SW Large"]
          }
        } 
      },
    }
  },
}

Some side notes:

Instead of "additionalProperties":false please use "propertyNames". It's been specifically introduced for purpose of making sure only demanded properties are present in JSON object validated aginst schema.

"propertyNames" : {
    "enum" : [
      "Registers"
    ]
  }

See: https://json-schema.org/understanding-json-schema/reference/object.html#property-names

It is very important to properly shape schemas/sub-schemas depending on which level these should be applied. Please note how "#/definitions/Fields-contains-at-least-1-element-with-SW-Large-true" properly reflects schema at "#/Registers/items" nesting level (since the "dependencies" is applied to an object on "#/Registers/items" level and one can think of it as of ""#/Registers/items/dependencies"). See https://json-schema.org/understanding-json-schema/reference/object.html#dependencies .

If you intend to validate single item of "Fields" array separately or even single item of "Registers" array separately, you might consider reshaping your schema to separate sub-schemas like I did with "questionA" in here: https://stackoverflow.com/a/53309856/2811843 . Thus - if necessity is there - you could easily exclude sub-schemas from main schema and just properly reference to them using "$ref" keyword. Some reading on JSON Pointer and relative JSON Pointer might be also useful for structuring complex schemas.

Worth to start at: https://json-schema.org/understanding-json-schema/structuring.html

I hope it helped.

Answer from PsychoFish on Stack Overflow
🌐
JSON Schema
json-schema.org › understanding-json-schema › reference › conditionals
JSON Schema - Conditional schema validation
Previously to Draft 2019-09, dependentRequired and dependentSchemas were one keyword called dependencies. If the dependency value was an array, it would behave like dependentRequired and if the dependency value was a schema, it would behave like dependentSchema.
🌐
MongoDB
mongodb.com › blog › post › json-schema-validation--dependencies-you-can-depend-on
JSON Schema Validation - Dependencies you can depend on | MongoDB Blog
November 18, 2019 - Schema dependencies which define a change in the schema when a given property is present. An example use case of property dependencies would be students. If a student has graduated from a program, we want to stay in touch with them and want ...
Discussions

jsonschema - JSON schema conditional dependency on value - Stack Overflow
I know there is a similar question here, but it didn't really address my issue. In short, I want one my fields to be dependent on the other field's value. But for some values, I don't want any fiel... More on stackoverflow.com
🌐 stackoverflow.com
Proposal: Add propertyDependencies keyword (aka discriminator)
Compared to discriminator, this is more consistent with the style of JSON Schema keywords because it doesn't use sub-keywords like propertyName and mappings. It's also more powerful because it allows you to discriminate using more than one property. Because of the parallels to dependencies, I chose ... More on github.com
🌐 github.com
38
March 22, 2021
dependencies - JSON Schema - specify field is required based on value of another field - Stack Overflow
Wondering if this is possible with schema draft 03. I've gotten dependencies working elsewhere, I think there is possibly just some creative use of them required in order to use them for specifying... More on stackoverflow.com
🌐 stackoverflow.com
Is it possible to have "dependencies" based on values instead of presence?
json-schema / json-schema Public ... kriszyp/json-schema ... This repository was archived by the owner on Mar 19, 2019. It is now read-only. ... if (drink.name == 'beer' || drink.name == 'wine') // "color" is a required fiels else if (drink.name == "water") // nothing is required · Maybe i'm wrong but I can't find a way to implement this case, dependencies keyword seems ... More on github.com
🌐 github.com
3
March 25, 2015
Top answer
1 of 1
1

Yuk, upward dependencies can be really unpleaseant. Does the model have to be shaped that way?

Solution

You are on the right track. What you are missing is checking correctly if at least one element of "Fields" array had that "SW Large" : true and then shape the proper dependency.

Since draft-06 it is solved with "contains" keyword. In order to not repeat content, I'd recommend to read following:

JSON Schema: How to check that an array contains at least one object with a property with a given value?

Json Schema: Require a property only when a specific property is present in a deep nested object (very educational!)

https://json-schema.org/understanding-json-schema/reference/array.html

Your schema re-worked below. See the "definitions" section

First of all it's adding "contains" : { schema } to "Fields" definition. I need it as separate schema in order to use it as a condition in logical implication.

"definitions" : {
    "Fields-contains-at-least-1-element-with-SW-Large-true" : {
      "properties": { 
        "Fields" : {
          "contains" : {
            "properties": { 
              "SW Large": { "enum": [true] } 
            },
            "required" : ["SW Large"]
          }
        } 
      },
    }
  },

If you would add it permanently, it might look like:

"Fields" : {
  "type" : "array",
  "contains" : {
    "properties": { 
      "SW Large": { "enum": [true] } 
    },
    "required" : ["SW Large"]
  }
  "items": {...},
}

which translates to "at least one item of "Fields" array must contain object with said property name and said value". Every JSON with "Fields" array that contains no item with "SW Large" : true would fail validation against such schema. And if you reverse the "contains" schema definition like:

"Fields" : {
    "type" : "array",
    "contains" : {
      "not" : {
        "properties": { 
          "SW Large": { "enum": [true] } 
        },
        "required" : ["SW Large"]
      }
    }
    "items": {...},
  }

it would translate to "no item of "Fields" array can contain object with said property name and said value". Every JSON with "Fields" array that contains at least one item with "SW Large" : true would fail validation against such schema.

I don't want any of above to happen. I want to link "Fields/contains" condition with requiring or not requiring the "SW Words" property one level above, hence getting schema excluded to "definitions" section and making a proper use of it.

The "upward-dependency" is defined using that check and proper logical implication with "anyOf" keyword

It doesn't contain at least 1 item with "SW Large" : true OR "SW Words" is required

"definitions" : {
    "upward-dependency" : {
      "anyOf" : [
        { "not" : {"$ref" : "#/definitions/Fields-contains-at-least-1-element-with-SW-Large-true"} },
        { "required" : ["SW Words"] }
      ]
    },
  },

At the level of single item of "Registers" array I've added the "dependencies". Whenever "Fields" item appear in one of "Registers" items, it's been checked if it contains the unfortunate "SW Large" : true and if it does - the "SW Words" becomes required. Voila!

       "items" : {
        "$id": "#/properties/Registers/items
        "type" : "object",
        "properties" : {
          "Fields": {
            "$id": "#/properties/Registers/items/properties/Fields",
            "type": "array",
            "items": {
              "$id": "#/properties/Registers/items/properties/Fields/items",
              "type": "object",
              "propertyNames" : {
                "enum" : [
                  "Name",
                  "SW Large"
                ]                
              },
              "required": [
                "Name"
              ],
              "properties": {
                "Name": {
                  "$id": "#/properties/Registers/items/properties/Fields/items/properties/Name",
                  "type": "string"
                },
                "SW Large": {
                  "$id": "#/properties/Registers/items/properties/Fields/items/properties/SW Large",
                  "type": "boolean"
                }
              }
            }
          }
        },
        "dependencies" : {
          "Fields" : { "$ref" : "#/definitions/upward-dependency" }
        },
      }

I've checked Schema with online validator and added your object to "examples" section.

Full schema:

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "$id": "http://example.com/root.json",
  "type": "object",
  "propertyNames" : {
    "enum" : [
      "Registers"
    ]
  },
  "required": [
    "Registers"
  ],
  "examples" : [
    {
      "Registers": [
        {
          "Name": "device",
          "Address": "100",
          "SW Words": 2,
          "Fields": [
            {
              "Name" : "Product",
              "SW Large" : true
            },
            {
              "Name": "Version"
            }
          ]
        }
      ]
    }
  ],
  "properties": {
    "Registers": {
      "$id": "#/properties/Registers",
      "type": "array",
      "items": {
        "$id": "#/properties/Registers/items",
        "type": "object",
        "propertyNames" : {
          "enum" : [
            "Name",
            "Address",
            "SW Words",
            "Fields"
          ]
        },
        "required": [
          "Name",
          "Address",
          "Fields"
        ],
        "properties": {
          "Name": {
            "$id": "#/properties/Registers/items/properties/Name",
            "type": "string"
          },
          "Address": {
            "$id": "#/properties/Registers/items/properties/Address",
            "type": "string"
          },
          "SW Words": {
            "$id": "#/properties/Sections/items/properties/Blocks/items/properties/SW Words",
            "type": "integer",
            "default": 2,
            "minimum": 2
          },
          "Fields": {
            "$id": "#/properties/Registers/items/properties/Fields",
            "type": "array",
            "items": {
              "$id": "#/properties/Registers/items/properties/Fields/items",
              "type": "object",
              "propertyNames" : {
                "enum" : [
                  "Name",
                  "SW Large"
                ]                
              },
              "required": [
                "Name"
              ],
              "properties": {
                "Name": {
                  "type": "string"
                },
                "SW Large": {
                  "type": "boolean"
                }
              }
            }
          }
        },
        "dependencies" : {
          "Fields" : { "$ref" : "#/definitions/upward-dependency" }
        },
      }
    }
  },
  "definitions" : {
    "upward-dependency" : {
      "anyOf" : [
        { "not" : {"$ref" : "#/definitions/Fields-contains-at-least-1-element-with-SW-Large-true"} },
        { "required" : ["SW Words"] }
      ]
    },
    "Fields-contains-at-least-1-element-with-SW-Large-true" : {
      "properties": { 
        "Fields" : {
          "contains" : {
            "properties": { 
              "SW Large": { "enum": [true] } 
            },
            "required" : ["SW Large"]
          }
        } 
      },
    }
  },
}

Some side notes:

Instead of "additionalProperties":false please use "propertyNames". It's been specifically introduced for purpose of making sure only demanded properties are present in JSON object validated aginst schema.

"propertyNames" : {
    "enum" : [
      "Registers"
    ]
  }

See: https://json-schema.org/understanding-json-schema/reference/object.html#property-names

It is very important to properly shape schemas/sub-schemas depending on which level these should be applied. Please note how "#/definitions/Fields-contains-at-least-1-element-with-SW-Large-true" properly reflects schema at "#/Registers/items" nesting level (since the "dependencies" is applied to an object on "#/Registers/items" level and one can think of it as of ""#/Registers/items/dependencies"). See https://json-schema.org/understanding-json-schema/reference/object.html#dependencies .

If you intend to validate single item of "Fields" array separately or even single item of "Registers" array separately, you might consider reshaping your schema to separate sub-schemas like I did with "questionA" in here: https://stackoverflow.com/a/53309856/2811843 . Thus - if necessity is there - you could easily exclude sub-schemas from main schema and just properly reference to them using "$ref" keyword. Some reading on JSON Pointer and relative JSON Pointer might be also useful for structuring complex schemas.

Worth to start at: https://json-schema.org/understanding-json-schema/structuring.html

I hope it helped.

🌐
Readthedocs
react-jsonschema-form.readthedocs.io › en › v1.8.1 › dependencies
Dependencies - react-jsonschema-form documentation
{ "type": "object", "properties": ... courtesy of the Space Telescope Science Institute) The JSON Schema standard says that the dependency is triggered if the property is present....
🌐
Liquid Technologies
liquid-technologies.com › Reference › XmlStudio › JsonEditorNotation_SchemaDependency.html
Schema Dependency
JSON Schema Editor / Graphical Notation Overview / Dependency Container / Schema Dependency · Collapse All Expand All · In This Topic · Schema Dependency · In This Topic · A schema dependency has a named property and a sub schema. If the named property exists, then the schema is applied ...
Top answer
1 of 3
14

You can do this with a boolean logic concept called implication (!A or B). It can be used like an "if-then" statement. For example, either "color" is not "red" or "redQuote" is required. Any time I need to use this, I break it down with definitions so it reads as nice as possible.

{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "colour": { "enum": ["red", "black", "blue"] },
    "blackQuote": { "type": "string", "maxLength": 11 },
    "redQuote": { "type": "string", "maxLength": 11 }
  },
  "allOf": [
    { "$ref": "#/definitions/red-requires-redQuote" },
    { "$ref": "#/definitions/black-requires-blackQuote" }
  ],
  "required": ["colour"],
  "definitions": {
    "red-requires-redQuote": {
      "anyOf": [
        { "not": { "$ref": "#/definitions/is-red" } },
        { "required": ["redQuote"] }
      ]
    },
    "black-requires-blackQuote": {
      "anyOf": [
        { "not": { "$ref": "#/definitions/is-black" } },
        { "required": ["blackQuote"] }
      ]
    },
    "is-red": {
      "properties": {
        "colour": { "enum": ["red"] }
      },
      "required": ["colour"]
    },
    "is-black": {
      "properties": {
        "colour": { "enum": ["black"] }
      },
      "required": ["colour"]
    }
  }
}
2 of 3
6

Simplest answer in draft-04 (as noted by Ganesh in a comment):

{
  "definitions": {},
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {

    "colour": {
      "type": "string",
      "enum": ["red", "black", "blue"]
    },

    "blackQuote": {
      "type": "string",
      "maxLength": 11
    },

    "redQuote": {
      "type": "string",
      "maxLength": 11
    }
  },

  "oneOf": [
      {
        "properties": {
          "colour": {"enum": ["red"]}
        },
        "required": ["redQuote"]
      },
      {
        "properties": {
          "colour": {"enum": ["black"]}
        },
        "required": ["blackQuote"]
      },
      {
        "properties": {
          "colour": {"enum": ["blue"]}
        }
      }
  ],

  "required": [
    "colour"
  ]
}
🌐
Rjsf-team
rjsf-team.github.io › json schema › dependencies
Dependencies | react-jsonschema-form
import { RJSFSchema } from ... courtesy of the Space Telescope Science Institute) The JSON Schema standard says that the dependency is triggered if the property is present....
🌐
Learnjsonschema
learnjsonschema.com › 2020-12 › validation › dependentrequired
dependentRequired (2020-12) - Learn JSON Schema
For example, if a schema marks the property B as required if the property A is present and also marks the property C as required if the property B is present, defining the property A transitively requires both the B and C properties to be present in the object instance. The dependentSchemas keyword is a generalisation of this keyword to describe object dependencies beyond property requirement. Remember that JSON ...
Find elsewhere
🌐
GitHub
github.com › json-schema-org › json-schema-spec › issues › 1082
Proposal: Add propertyDependencies keyword (aka discriminator) · Issue #1082 · json-schema-org/json-schema-spec
March 22, 2021 - Right now, we have the dependentSchemas keyword that is very close to what is needed except it checks for the presence of a property rather than it's value.
Author   jdesrosiers
🌐
Learnjsonschema
learnjsonschema.com › draft4 › validation › dependencies
dependencies (Draft 4) - Learn JSON Schema
Note that multiple potentially ... every dependency must be transitively fulfilled for the object instance to be valid. For example, if a schema marks the property B as required if the property A is present and also marks the property C as required if the property B is present, defining the property A transitively requires both the B and C properties to be present in the object instance. Remember that JSON Schema is ...
🌐
To The New
tothenew.com › home › using "dependencies" in json schema (version : draft-v4)
Using “dependencies” in json schema (version : draft-v4) | TO THE NEW Blog
March 22, 2016 - Json Schema has another interesting ... be done using "dependencies" which allows specifying dependent object / property on the basis of value of the field which is using dependencies keyword....
🌐
Ajv
ajv.js.org › json-schema.html
JSON Schema | Ajv JSON schema validator
The value of the keyword is a map with keys equal to data object properties. Each value in the map should be either an array of unique property names ("property dependency" - see dependentRequired keyword) or a JSON Schema ("schema dependency" - see dependentSchemas keyword).
🌐
Learnjsonschema
learnjsonschema.com › 2020-12 › applicator › dependentschemas
dependentSchemas (2020-12) - Learn JSON Schema
The dependentRequired keyword is a specialisation of this keyword to describe object dependencies that only consist in property requirement. Remember that JSON Schema is a constraint-driven language. Therefore, non-object instances successfully validate against this keyword.
🌐
Rjsf-team
rjsf-team.github.io › json schema
JSON Schema | react-jsonschema-form
Dependencies can be used to create dynamic schemas that change fields based on what data is entered. ... The simplest example of a JSON Schema contains only a single field.
🌐
Google Groups
groups.google.com › g › json-schema › c › e4xVu24JUgM
JSON Schema Validation - dependencies example
However: the "dependencies" keyword only changes behaviour based on the presence/absence of a particular property in an object.
🌐
Google Groups
groups.google.com › g › json-schema › c › qrENvr8PBkM
JSON Schema - Dependencies between two "enums"
You can't. Validation of a given piece of data against a given schema can not depend on the data's parent or siblings - only on its children. The only way to do this is to provide multiple options (using oneOf/anyOf) in the parent schema. ... Either email addresses are anonymous for this group ...
🌐
GitHub
github.com › json-schema › json-schema › issues › 158
Is it possible to have "dependencies" based on values instead of presence? · Issue #158 · json-schema/json-schema
March 25, 2015 - { "type": "object", "properties": { "name": { "type": "string", "enum": ["beer", "wine", "water"] }, "color" : { "type": "string" } }, "required": ["name"], "dependencies": { "name": ["color"] // I can't specify the value of name } }
Author   marqu3z
Top answer
1 of 3
456

Depending on your situation, there are a few different approaches. I can think of four different ways to conditionally require a field.

Dependencies

The dependentSchemas keyword is a conditional way to apply a schema. Foreach property in dependentSchemas, if the property is present in the JSON being validated, then the schema associated with that key must also be valid. If the "foo" property is present, then the "bar" property is required

{
  "type": "object",
  "properties": {
    "foo": { "type": "string" },
    "bar": { "type": "string" }
  },
  "dependentSchemas": {
    "foo": { "required": ["bar"] }
  }
}

If all the dependent schema needs is the required keyword, you can use the dependentRequired keyword as a shorthand. The following has the same effect as the previous example.

{
  "type": "object",
  "properties": {
    "foo": { "type": "string" },
    "bar": { "type": "string" }
  },
  "dependentRequired": {
    "foo": ["bar"]
  }
}

NOTE: In draft-07 and below these were one keyword called dependencies. If the value is a schema it behaved like dependentSchemas. If the value is an array, it behaved like dependentRequired.

Implication

If your condition depends on the value of a field, you can use a boolean logic concept called implication. "A implies B" effectively means, if A is true then B must also be true. Implication can also be expressed as "!A or B". Either the "foo" property does not equal "bar", or the "bar" property is required. Or, in other words: If the "foo" property equals "bar", Then the "bar" property is required

{
  "type": "object",
  "properties": {
    "foo": { "type": "string" },
    "bar": { "type": "string" }
  },
  "anyOf": [
    {
      "not": {
        "properties": {
          "foo": { "const": "bar" }
        },
        "required": ["foo"]
      }
    },
    { "required": ["bar"] }
  ]
}

If "foo" is not equal to "bar", #/anyOf/0 matches and validation succeeds. If "foo" equals "bar", #/anyOf/0 fails and #/anyOf/1 must be valid for the anyOf validation to be successful.

NOTE: The if/then keywords have the same behavior, but are easier to read and maintain. It's recommended to only use this approach if you are using an older version of JSON Schema that doesn't support if/then.

Enum

If your conditional is based on an enum, it's a little more straight forward. "foo" can be "bar" or "baz". If "foo" equals "bar", then "bar" is required. If "foo" equals "baz", then "baz" is required.

{
  "type": "object",
  "properties": {
    "foo": { "enum": ["bar", "baz"] },
    "bar": { "type": "string" },
    "baz": { "type": "string" }
  },
  "anyOf": [
    {
      "properties": {
        "foo": { "const": "bar" }
      },
      "required": ["bar"]
    },
    {
      "properties": {
        "foo": { "const": "baz" }
      },
      "required": ["baz"]
    }
  ]
}

NOTE: This approach is not recommended because it can produce confusing error messages. The if/then keywords are generally a better approach.

If-Then-Else

The if, then and else keywords are shorthand for the implication pattern described above. These keywords were added in draft-07. If the "foo" property equals "bar", Then the "bar" property is required

{
  "type": "object",
  "properties": {
    "foo": { "type": "string" },
    "bar": { "type": "string" }
  },
  "if": {
    "properties": {
      "foo": { "const": "bar" }
    },
    "required": ["foo"]
  },
  "then": { "required": ["bar"] }
}

EDIT 12/23/2017: Implication section updated and If-Then-Else section added.

EDIT 06/04/2018: Bugfix for If-Then-Else and update singleton enums to use const.

EDIT 07/06/2022: Update Dependencies section to use the new dependentSchemas/dependentRequired keywords instead of dependencies.

2 of 3
6

As of 2022, dependencies has been deprecated, and split into dependentRequired (see e.g. this example) and dependentSchemas (see e.g. this example). Just using dependentRequired solves the issue:

{
  "type": "object",
  "properties": {
    "foo": { "type": "string" },
    "bar": { "type": "string" }
  },
  "dependentRequired": {
    "foo": ["bar"]
  }
}
🌐
JSON Schema
json-schema.org › understanding-json-schema › reference › object
JSON Schema - object
Objects are the mapping type in JSON. They map "keys" to "values". In JSON, the "keys" must always be strings. Each of these pairs is conventionally referred to as a "property" · In Python, "objects" are analogous to the dict type. An important difference, however, is that while Python ...