Search code examples
jsonpostmanjsonschema

How to validate json with some conditions


There is some json.

{
  "headerInfo": {
    "id": 50
  "characteristics": [
    {
      "id": "123456789",
      "type": "float",
      "multiValued": false,
      "numberDecimals": 6,
      "length": 10,
      "caseSensitive": false,
      "entryFieldMask": "_,___.______",
      "unitOfMeasure": "P1",
      "additionalValues": true
    },
    {
      "id": "15151511",
      "type": "float",
      "multiValued": false,
      "numberDecimals": 0,
      "possibleValues": [
        {
          "valueLow": "60",
          "intervalType": "1"
        },
        {
          "valueLow": "80",
          "intervalType": "1"
        }
      ],
      "length": 3,
      "caseSensitive": false,
      "entryFieldMask": "___",
      "unitOfMeasure": "P1",
      "additionalValues": false
    },
    {
      "id": "489481561",
      "type": "string",
      "multiValued": false,
      "possibleValues": [
        {
          "id": "A"
        }
        {
          "id": "§"
        }
      ],
      "length": 1,
      "caseSensitive": true,
      "entryFieldMask": "",
      "additionalValues": false,
      "reference": {
        "name": "ghnfgjghjghk",
        "writable": false
      }
    },
    {
      "id": "4616616161",
      "type": "date",
      "multiValued": false,
      "length": 10,
      "caseSensitive": false,
      "entryFieldMask": "DD.MM.YYYY",
      "additionalValues": true,
      "reference": {
        "name": "bfhwbvbjewbv",
        "writable": false
      }
    }
  ]
}

How to generate a json schema using the following conditions:

  • the "reference" and "possibleValues" properties are optional.
  • if the "type" property is equal to the "float" value, then the "numberDecimals" property is required, otherwise it is not.

I tried to implement this using anyOf, but in this case everything inside anyOf was not validated correctly, although in the postman validation was successful.


Solution

  • You can use the if, then syntax with JSON Schema draft-07 or newer.

    The jist is you define the entire schema, and then at the object schema where you want to define required properties, you add the if, then syntax to check if the value matches the condition, then assign the then constraint.

    In your case, we check if the constant value of type is float, if true, required:["numberDecimals"]

    {
      "$schema": "http://json-schema.org/draft-07/schema#",
      "type": "object",
      "properties": {
        "headerInfo": {
          "properties": {
            "id": {
              "type": "number"
            }
          }
        },
        "characteristics": {
          "type": "array",
          "uniqueItems": true,
          "items": {
            "properties": {
              "id": {
                "type": "string"
              },
              "type": {
                "type": "string"
              },
              "multiValued": {
                "type": "boolean"
              },
              "numberDecimals": {
                "type": "number"
              },
              "length": {
                "type": "number"
              },
              "caseSensitive": {
                "type": "boolean"
              },
              "entryFieldMask": {
                "type": "string"
              },
              "unitOfMeasure": {
                "type": "string"
              },
              "additionalValues": {
                "type": "boolean"
              },
              "reference": {
                "properties": {
                  "name": {
                    "type": "string"
                  },
                  "writable": {
                    "type": "boolean"
                  }
                }
              },
              "possibleValues": {
                "type": "array",
                "uniqueItems": true,
                "items": {
                  "oneOf": [
                     {
                       "properties": {
                          "id": {
                            "type": "string"
                          }
                       }
                     },
                     {
                       "properties": {
                          "valueLow": {
                             "type": "string"
                          },
                          "intervalType": {
                             "type": "string"
                          }
                       }
                     }
                   ]
                }
              }
            },
            "if": {
              "properties": {
                "type": {
                  "const": "float"
                }
              }
            },
            "then": {
              "required": [
                "numberDecimals"
              ]
            },
            "required": [
              "id",
              "type",
              "multiValued",
              "length",
              "caseSensitive",
              "entryFieldMask",
              "additionalValues"
            ]
          }
        }
      }
    }