I'm building a json schema definition which has a fixed set of controls that I've currently limited with an enum. However, not all properties are relevant for all controls.

I only want to require an options property if the controlType = dropdown

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "array",
  "items": {
    "type": "object",
    "properties": {
      "controlType": {
        "type": "string",
        "enum": ["title", "dropdown", "button"]
      },
      "options:": {
        "type": "array",
        "items": {"type": "string"}
      }
    }
  }
}

How can I conditionally include / require a field in a json schema?

Use IF..Then..Else <sup> new in Draft-07 </sup>

<!-- language: lang-js --> <pre><code>{ "$schema": "http://json-schema.org/draft-07/schema#", "type": "array", "items": { "type": "object", "properties": { "controlType": { "type": "string", "enum": ["title", "dropdown", "button"] }, "options:": { "type": "array", "items": {"type": "string"} } }, <b> "if": { "properties": { "controlType": {"const": "dropdown"} } }, "then": { "required": ["options"] }</b> } } </code></pre>

Use oneOf or anyOf

This can be useful if you have a property that has a limited number of acceptable values (such as an enum), but each possible value needs to be individually mapped.

<!-- language: lang-js --> <pre><code>{ "$schema": "http://json-schema.org/draft-07/schema#", "type": "array", "items": { "type": "object", "properties": { "controlType": { "type": "string", "enum": ["title", "dropdown", "button"] }, "options:": { "type": "array", "items": {"type": "string"} } },<b> "anyOf": [ { "properties": { "controlType": {"const": "dropdown"} }, "required": ["controlType", "options"] }, { "properties": { "controlType": {"const": "title"} }, "required": ["controlType"] }, { "properties": { "controlType": {"const": "button"} }, "required": ["controlType"] } ]</b> } } </code></pre>

Further Reading