djsumdog
djsumdog

Reputation: 2710

JSON schema which allows either an object or an array of those objects

Say I have a JSON schema that allows for an object like so:

...
  "assetMetadata": {
    "type": "object",
    "additionalProperties": false,
    "properties": { ... }
  }
...

So say I want to change this to allow either that same object OR an array of that particular object. Here is accepting just an array:

...
"assetMetadata": {
  "type": "array",
  "description": "...",
  "items": {
    "type": "object",
    "additionalProperties": false,
    "properties": {...}
}
...

The properties are the same (it's the same object, just the option for multiple instead of just one).

Interestingly enough in the project I'm working on, the unmarshaller can already handle both (it turns the single object into a sequence of size 1), so it's purely the validation that's preventing me from going forward. We want to maintain comparability with the existing API, which is the reason I can't just require an array now.

Upvotes: 6

Views: 7075

Answers (2)

David
David

Reputation: 426

The accepted answer was not working for me in the JSON schema validator.

The arrays were not being accepted.

I made some tweaks and changes to make it work, here is an example schema:

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "anyOf": [
    {
      "$ref": "#/definitions/commentObject"
    },
    {
      "type": "array",
      "description": "Array of Comment objects",
      "items": {
        "$ref": "#/definitions/commentObject"
      }
    }
  ],
  "definitions": {
    "commentObject": {
      "properties": {
        "number": {
          "type": "integer",
          "minLength": 0,
          "maxLength": 256
        },
        "comment": {
          "type": "string",
          "minLength": 0,
          "maxLength": 256
        }
      },
      "required": [
        "number",
        "comment"
      ],
      "type": "object"
    }
  }
}

Object used to test the validation:

{
  "number": 47,
  "comment": "This is a comment",
}

Arrays of objects used to test the validation:

[
  {
    "number": 47,
    "comment": "This is a comment"
  },
  {
    "number": 11,
    "comment": "This is other comment"
  }
]

JSON Schema Validator for object

JSON Schema Validator for array (of the same objects)

Upvotes: 0

Jason Desrosiers
Jason Desrosiers

Reputation: 24409

You can achieve this using the anyOf keyword and definitions/$ref to avoid duplication.

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "object",
  "properties": {
    "assetMetadata": {
      "anyOf": [
        { "$ref": "#/definitions/assetMetaData" },
        {
          "type": "array",
          "description": "...",
          "items": { "$ref": "#/definitions/assetMetaData" }
        }
      ]
    }
  },
  "definitions": {
    "assetMetadata": {
      "type": "object",
      "additionalProperties": false,
      "properties": { ... }
    }
  }
}

Upvotes: 15

Related Questions