Home > database >  How to create JSON Schema for an array of dictionaries with different type values
How to create JSON Schema for an array of dictionaries with different type values

Time:08-15

I have the following JSON file which I want to validate:

{"topic_name": "test_topic",
 "partitions": 15,
 "factor": 3,
 "configuration":
      [
          {"name": "retention.ms", "value": 302400000},
          {"name": "delete.retention", "value": "null"},
          {"name": "cleanup", "value": "delete"}
      ]
  }

I now validate using this Schema:

{
    "type": "object",
    "uniqueItems": true,
    "properties": {
        "factor": {
            "type": "number"
        },
        "partitions": {
            "type": "number",
            "minimum": 3,
            "maximum": 15
            },
        "configuration": {
            "type": "array",
            "uniqueItems": true,
            "prefixItems": [
                {
                    "type": "object",
                    "maxProperties": 2,
                    "properties": {
                        "name": {"type": "string"},
                        "value": {"type": "number"}
                    }
                },
                {
                    "type": "object",
                    "properties": {
                        "name": {"type": "string"},
                        "value": {"type": "string"}
                    }
                },
                {
                    "type": "object",
                    "properties": {
                        "name": {"type": "string"},
                        "value": {"type": "string"}
                    }
                },
            ]
            }
           },
    "required": [
        "partitions_count",
        "replication_factor",
        "configs",
        "topic_name"
        ]
    }

The problem I face with my current schema is that the ordering is fixed. I want to validate each item in my configuration key to a different type. Retention should be integer, cleanup should be string. I do not know how to do this. I tried it with the "items" keyword, but although every "name" key should have a "string" value. The "value" key can have different classes requirements which is dependent on the name. Any ideas?

CodePudding user response:

JSON Schema is not designed to validate conditionally based on instance data. But it is possible to some extent using if-then-else (Tutorial) or oneOf/anyOf/allOf often in combination with const and pattern (Tutorial) checking:

{
  "type": "object",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "description": "JSON schema generated with JSONBuddy https://www.json-buddy.com",
  "properties": {
    "configuration": {
      "type": "array",
      "items": {
        "oneOf": [
          {
            "type": "object",
            "if": {
              "properties": {
                "name": {
                  "pattern": "cleanup"
                }
              }
            },
            "then": {
              "properties": {
                "value": {
                  "type": "string"
                }
              }            
            },
            "else": false
          },
          {
            "type": "object",
            "if": {
              "properties": {
                "name": {
                  "pattern": "delete.retention"
                }
              }
            },
            "then": {
              "properties": {
                "value": {
                  "type": "null"
                }
              }            
            },
            "else": false
          },
          {
            "type": "object",
            "if": {
              "properties": {
                "name": {
                  "pattern": "retention.ms"
                }
              }
            },
            "then": {
              "properties": {
                "value": {
                  "type": "integer"
                }
              }            
            },
            "else": false
          }
        ]
      }
    }
  }
}

Please note that you can use any regular expression with the pattern keyword.

  • Related