Указание объекта должно быть пустым, если другой объект имеет свойства в схеме JSON.

У меня есть данные, которые возвращаются из GraphQL, я хотел бы проверить эти данные с помощью схемы JSON, прежде чем манипулировать ими.

Может быть лучший способ сделать это в graphQL, чем я сейчас, но возвращаемые данные могут быть двух типов с одинаковыми свойствами:

например упрощенная версия данных

obj: {
  audio: {
    artists: []
  },
  video: {}
}

or

obj: {
  audio: {},
  video: {
    artists: []
  }
}

Таким образом, достоверность будет:

  • объект со свойствами audio и video
  • объект с audio как объект со свойством artists и пустой объект свойства video
  • объект с video как объект со свойством artists и пустой объект свойства audio
  • ни audio, ни video не должны быть пустыми вместе
  • ни audio, ни video не должны иметь вместе свойства

Я построил упрощенную схему, которая выглядит так:

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "$id": "file://schemas/simple.schema.json",
  "title": "simplified data",
  "description": "simple",
  "type": "object",
  "properties": {
    "audio": {
      "type": "object"
    },
    "video": {
      "type": "object"
    }
  },
  "oneOf": [
    {
      "audio": {
        "type": "object",
        "properties": {
          "artists": {
            "type": "array"
          }
        }
      },
      "video": {
        "type": "object",
        "properties": {}
      }
    },
    {
      "audio": {
        "type": "object",
        "properties": {}
      },
      "video": {
        "type": "object",
        "properties": {
          "artists": {
            "type": "array"
          }
        }
      }
    }
  ]
}

но AJV, похоже, неправильно проверяет данные при запуске:

{
  "audio": {
    "artists": []
  },
  "video": {}
}

Что я мог сделать не так с моей схемой?


person Jarede    schedule 06.05.2020    source источник


Ответы (1)


После первой попытки Джейсон указал на более простое решение...

С помощью oneOf можно указать, что только один из объектов может иметь хотя бы одно свойство.

Вы можете проверить это здесь: https://jsonschema.dev/s/SSRaL

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "$id": "file://schemas/simple.schema.json",
  "properties": {
    "audio": {
      "type": [
        "object"
      ],
      "properties": {
        "artists": {
          "$comment": "whatever validation you want"
        }
      }
    },
    "video": {
      "type": [
        "object"
      ],
      "properties": {
        "artists": {
          "$comment": "whatever validation you want"
        }
      }
    }
  },
  "oneOf": [
    {
      "properties": {
        "video": {
          "minProperties": 1
        }
      }
    },
    {
      "properties": {
        "audio": {
          "minProperties": 1
        }
      }
    }
  ]
}
person Relequestual    schedule 06.05.2020
comment
if/then не нужны. oneOf достаточно. Также "not": { "additionalProperties": false } можно упростить как "minProperties": 1. - person Jason Desrosiers; 06.05.2020
comment
Да на самом деле ты прав. Я добавил oneOf после других частей схемы. Я обновлю ответ, чтобы отразить. Спасибо. - person Relequestual; 07.05.2020