0

I trying to create a json schema for an object which can contain either array of expressions or array of arrays of expression etc. with any number of levels.

This is what I got so far:

  {
  "type": "object",
  "properties": {
    "expression": {
      "type": "array",
      "items": {
        "anyOf": [
          {
            "$ref": "#/definitions/singleQuery"
          },
          {
            "$ref": "#/definitions/orGroup"
          }
        ]
      },
      "minItems": 1
    }
  },
  "definitions": {
    "orGroup": {
      "type": "object",
      "properties": {
        "or": {
          "type": "array",
          "items": {
            "anyOf": [
              {
                "$ref": "#/definitions/singleQuery"
              },
              {
                "$ref": "#/definitions/orGroup"
              }
            ]
          },
          "minItems": 1,
          "additionalProperties": false
        }
      }
    },
    "singleQuery": {
      "type": "object",
      "properties": {
        "queryString": {
          "type": "string"
        },
        "disabled": {
          "type": "boolean"
        }
      },
      "required": [
        "queryString"
      ]
    }
  }
}

However I am using https://www.jsonschemavalidator.net/ to verify schema is working correctly and with such implementation data like the following will still pass the validation:

{
  "expression": [{}]
}

What I am trying to accomplish is validation to expect expression object always have either orGroup or/and singleQuery and orGroup should always require at least one object with queryString. orGroups can be nested in any number of levels, but can't be empty. Here is an example of query:

{
  "expression": [
    {
      "or": [
        {
          "or": [
            {
              "queryString": "SELECT * from users WHERE..."
            },
            {
              "queryString": "SELECT * from users WHERE..."
            }
          ]
        },
        {
          "queryString": "SELECT * from users WHERE..."
        }
      ]
    },
    {
      "queryString": "SELECT * from users WHERE..."
    }
  ]
}

This query should pass but it wouldn't if at least one of the object didn't have a queryString.

atri
  • 81
  • 4
  • Perhaps you need to specify that `orGroup` has a mandatory property `or`? – Vilx- May 18 '21 at 14:30
  • @Vilx- The empty expression will still pass the validation unfortunately. However orGroup should have either another orGroup or an object with queryString. And with any levels of orGroups the last one should always contain at least one query string. I'll update the question to add an example. – atri May 18 '21 at 14:37
  • It's preferable if you can show your WHOLE schema, as you've only included `definitions` at the root level, which doesn't imply any validation by itself. – Relequestual May 18 '21 at 15:35
  • Why would an empty expression pass? `{"expression":[]}` is invalid, because it has `minItems:1`. And `{"expression":[{}]}` will be invalid, because `required:["or"]` and `required:[ "queryString"]` which makes it both an invalid `singleQuery` and an invalid `orGroup`. – Vilx- May 18 '21 at 15:56
  • 1
    @Relequestual I made a mistake when pasting a query. I fixed the question. – atri May 18 '21 at 16:12
  • The answer in the question I linked to above should cover what you're looking for. If not, please let me know why not =] – Relequestual May 18 '21 at 16:15
  • @Relequestual Thank you! I’ll give another try and tell you – atri May 18 '21 at 16:18
  • 1
    @Relequestual I accepted your answer :) Indeed a combination of cyclical reference and additionalProperties was a way to go. Thank you! – atri May 19 '21 at 11:02
  • You're welcome! Should you find a question you can't ask on SO, feel free to join our Slack server. – Relequestual May 19 '21 at 14:22

0 Answers0