Anuj TBE
Anuj TBE

Reputation: 9796

JSON Schema for child objects with different set of keys

I have JSON data of which is an array of data like

[
  {
    "type": "background_color",
    "data": {
      "backgroundColor": "F9192D"
    }
  },
  {
    "type": "banner_images",
    "data": {
      "images": [
        {
          "url": "https://example.com/abc.jpg",
          "id": 3085
        },
        {
          "url": "https://example.com/zyx.jpg",
          "id": 3086
        }
      ]
    }
  },
  {
    "type": "description_box",
    "data": {
      "text": "Hello 56787"
    }
  }
]

The data is an array of object which has two keys type and data. The type and keys of the data will be defined by the type of data it has.

Like for background_color type, the data should have backgroundColor property, while for banner_images, data should have images which is an array of other properties.

Till now, What I have done is

{
  "definitions": {},
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "array",
  "title": "category schema",
  "description": "Used to validate data of category",
  "examples": [],
  "required": [],
  "items": {
    "type": "object",
    "required": [
      "type",
      "data"
    ],
    "properties": {
      "type": {
        "type": "string",
        "enum": ["background_color", "banner_images", "description_box"]
      },
      "data": {
        "type": "object"        // How to define data property here for each use case
      }
    }
  }
}

I'm not getting how to define the data property for each use case?

Upvotes: 1

Views: 1518

Answers (1)

Relequestual
Relequestual

Reputation: 12355

You can use if/then/else blocks to define conditional constraints.

The values of if and then are schemas. If the if schema is valid, then the then schema is applied, otherwise, the allOf subschema (allOf[0] in this example) would pass validation.

There are a few different ways to do this, but this is clean when you don't have any additional or special requirements. Please come back if you do =]

In this example, I've added banner_images...

You can test it working here.

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "array",
  "title": "category schema",
  "description": "Used to validate data of category",
  "items": {
    "type": "object",
    "required": [
      "type",
      "data"
    ],
    "properties": {
      "type": {
        "type": "string",
        "enum": [
          "background_color",
          "banner_images",
          "description_box"
        ]
      },
      "data": {
        "type": "object"
      }
    },
    "allOf": [
      {
        "if": {
          "properties": {
            "type": {
              "const": "banner_images"
            }
          }
        },
        "then": {
          "properties": {
            "data": {
              "required": [
                "images"
              ],
              "properties": {
                "images": {
                  "type": "array"
                }
              }
            }
          }
        }
      }
    ]
  }
}

For reference, here's the part of the JSON Schema draft-7 spec document that details the behaviour: https://datatracker.ietf.org/doc/html/draft-handrews-json-schema-validation-01#section-6.6

Upvotes: 1

Related Questions