8

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?

KyleMit
  • 30,350
  • 66
  • 462
  • 664
Dvirm
  • 83
  • 1
  • 1
  • 3

1 Answers1

8

Use IF..Then..Else new in Draft-07

{
  "$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"}
      }
    },
      
    "if": {
      "properties": {
        "controlType": {"const": "dropdown"}
      }
    },
    "then": {
      "required": ["options"]
    }
  }
}

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.

{
  "$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"}
      }
    },  
    "anyOf": [
      {
        "properties": {
          "controlType": {"const": "dropdown"}
        },
        "required": ["controlType", "options"]
      },
      {
        "properties": {
          "controlType": {"const": "title"}
        },
        "required": ["controlType"]
      },
      {
        "properties": {
          "controlType": {"const": "button"}
        },
        "required": ["controlType"]
      }
    ]
  }
}

Further Reading

KyleMit
  • 30,350
  • 66
  • 462
  • 664
  • But how do you do this when using `$ref`?? I have an enum defined in a different file, how do I forge an object to have a property for each enum value in that instance? – Douglas Gaskell Dec 22 '21 at 00:34