如果另一个对象在 JSON 模式中具有属性,则指定一个对象应该为空

Specifying an object should be empty if another object has properties in JSON schema

我有从 GraphQL 返回的数据,我想在处理数据之前使用 JSON 模式验证该数据。

在 graphQL 中可能有比我现在更好的方法来执行此操作,但返回的数据可以是具有相同属性的两种类型:

例如数据的简化版本

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

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

所以有效性为:

我构建了一个如下所示的简化模式:

{
  "$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": {}
}

我的架构可能出了什么问题?

经过初步尝试,Jason 指出了一个更简单的解决方案...

使用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
        }
      }
    }
  ]
}