Search code examples
jsonschemapython-jsonschema

Json schema: is it possible to validate a string is a JSON array or object?


For some reason, I have a property, say "references", that is a JSON string itself.

    "references": {
      "type": "string"
    },

But I want to validate the string is a JSON array (after "decoding"):

    "references": {
      "type": "array",
      "items": {
        "type": "string",
        "format": "uri"
      }
    },

Is it possible to do this with json schema? Same question for JSON objects.

A example of data:

{"references": "[\"ref 1\", \"ref 2\"]"}

Solution

  • The short answer is no, JSON Schema doesn't know how to express this constraint. You do have a few options tho.

    Option 1: contentMediaType

    The contentMediaType and contentEncoding keywords used to be part of the JSON Hyper-Schema specification, but it was moved to JSON Schema validation specification in draft-07. These keywords are used to describe non-JSON content as a string. However, I see no reason why you couldn't use it to describe JSON data as a string as well. This is only a partial solution as it only enforces that the string is JSON and not a JSON array. Also, you might have a hard time finding a validator that supports this (partially because it's new and partially because it's an uncommon use case)

    {
      "type": "string",
      "contentEncoding": "utf-8",
      "contentMediaType": "application/json"
    }
    

    http://json-schema.org/latest/json-schema-validation.html#rfc.section.8

    Option 2: custom format

    Some validators allows you to define custom formats for the format keyword. The downside of this is that you are tied to a particular implementation.

    {
      "type": "string",
      "format": "json-array"
    }
    

    Option 3: pattern

    I'm not even sure this one is possible, but you could try to come up with a regular expression that matches the JSON structure you're looking for.

    {
      "type": "string",
      "pattern": "... some god awful regex that probably won't work anyway ..."
    }