Anuj TBE
Anuj TBE

Reputation: 9790

How do I limit the maximum number of items in array by type using JSON Schema?

I have a json-schema (draft-07) of type array to store multiple types of data like

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "array",
  "items": {
    "type": "object",
    "required": [
      "type",
      "data"
    ],
    "additionalProperties": false,
    "properties": {
      "type": {
        "type": "string",
        "enum": [
          "banner_images",
          "description_box",
          "button"
        ]
      },
      "data": {
        "type": "object"
      }
    },
    "allOf": [
      {
        "if": {
          "properties": {
            "type": {
              "const": "banner_images"
            }
          }
        },
        "then": {
          "properties": {
            "data": {
              "$ref": "components/banner_images.json"
            }
          }
        }
      },
      {
        "if": {
          "properties": {
            "type": {
              "const": "description_box"
            }
          }
        },
        "then": {
          "properties": {
            "data": {
              "$ref": "components/description_box.json"
            }
          }
        }
      },
      {
        "if": {
          "properties": {
            "type": {
              "const": "button"
            }
          }
        },
        "then": {
          "properties": {
            "data": {
              "$ref": "components/button.json"
            }
          }
        }
      }
    ]
  }
}

Which validates the following data

[
  {
    "type": "banner_images",
    "data": {
      "images": [
        {
           "url": "https://example.com/image.jpg"
        }
      ]
    }
  },
  {
    "type": "description_box",
    "data": {
      "text": "Description box text"
    }
  },
  {
    "type": "button",
    "data": {
      "label": "Click here",
      "color": {
        "label": "#ff000ff",
        "button": "#00ff00",
        "border": "#00ff00"
      },
      "link": "https://example.com"
    }
  }
]

As of now, the user can provide any number of the components from banner_images, description_box, and button.

I want to limit each component based on the component type

There is an option to set the length of the items in array type https://json-schema.org/understanding-json-schema/reference/array.html#id7

But how can I limit the length of the items based on the type?

Upvotes: 1

Views: 2311

Answers (1)

Ether
Ether

Reputation: 53966

You can do that by combining "contains" and "maxContains" (note this requires an implementation that supports draft version 2019-09 or later.)

In pseudocode: the components array has items containing objects with a property "type". When "type" is "banner_images", a maximum of 1 such item may exist. When "type" is "description_box", a maximum of 5 such item may exist. When "type" is "button", a maximum of 10 such item may exist.

That is:

  "items": {
    "type": "object",
    ...
  },
  "allOf": [
    {
       "contains": {
         "properties": {
            "type": {
              "const": "banner_images"
            }
         }
       },
       "minContains": 0,
       "maxContains": 1
    },
    {
       "contains": {
         "properties": {
            "type": {
              "const": "description_box"
            }
         }
       },
       "minContains": 0,
       "maxContains": 5
    },
    {
       "contains": {
         "properties": {
            "type": {
              "const": "button"
            }
         }
       },
       "minContains": 0,
       "maxContains": 10
    },
  ]


Upvotes: 2

Related Questions