Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 269
djsumdog Avatar asked Apr 04 '16 21:04

djsumdog


People also ask

What is JSON Object schema?

JSON (JavaScript Object Notation) is a simple and lightweight text-based data format. JSON Schema is an IETF standard providing a format for what JSON data is required for a given application and how to interact with it.

What are JSON schemas used for?

JSON Schema is a lightweight data interchange format that generates clear, easy-to-understand documentation, making validation and testing easier. JSON Schema is used to describe the structure and validation constraints of JSON documents.


1 Answers

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": { ... }
    }
  }
}
like image 73
Jason Desrosiers Avatar answered Nov 23 '22 06:11

Jason Desrosiers