jsonschema 没有在缺少时抛出错误 属性

jsonschema not throwing error on missing required property

我有以下架构:

const LIST_EVENTS = {
    "id": "/listEvents",
    "type": "object",
    "properties": {
        "filter": {
            "$ref": "/MarketFilter",
            "required": true
        },
        "locale": {
            "type": "string"
        }
    }
}

从调试中,我可以看到发送到验证的对象是:

{
    marketFilter: {
        eventTypeIds: [ '1' ],
        marketStartTime: {
            from: '2018-12-15T00:00:00+00:00',
            to: '2018-12-15T23:59:59+00:00'
        }
    }
}

marketFilter 与架构中 filter 的名称不匹配。据我了解,鉴于这是必需的 属性,这应该已在验证结果的 errors 数组中标记,但事实并非如此。这是我的验证结果:

ValidatorResult {
  instance:
    { marketFilter: { eventTypeIds: [Array], marketStartTime: [Object] } },
  schema:
    { id: '/listEvents',
      type: 'object',
      properties: { filter: [Object], locale: [Object] } },
  propertyPath: 'instance',
  errors: [],
  throwError: undefined,
  disableFormat: false }

我认为它可能不介意命名约定,所以我完全删除了 属性,但仍然没有记录错误,这是验证结果:

ValidatorResult {
  instance: {},
  schema:
    { id: '/listEvents',
      type: 'object',
      properties: { filter: [Object], locale: [Object] } },
  propertyPath: 'instance',
  errors: [],
  throwError: undefined,
  disableFormat: false }

我有很多模式,它们都是通过.addSchema方法添加的

目前,我找到了文档中也有描述的解决方法。我已将 required 数组 属性 添加到架构中,并向其添加了 filter。这现在引发了错误。

但是,文档指出 属性 上的 required 属性 本身应该工作相同。如果 属性 是引用,这是否可能是包的问题或是否有不同的行为?

您的架构有两个问题。主要问题是您的 required 关键字被忽略,因为它紧挨着 $ref。当在需要模式的地方遇到带有 $ref 关键字的对象时,它仅被视为 JSON 引用。它不被视为模式。 JSON 参考仅具有 $ref 关键字的语义。其他一切都被忽略。您可以通过在架构中隔离 $ref 来解决您的问题。

"filter": {
    "allOf": [{ "$ref": "/MarketFilter" }],
    "required": true
}

另一个问题是 required 关键字的布尔形式的使用。多年前,required 关键字的这种用法已从 JSON 架构规范中删除。除非您专门针对 draft-03 规范编写 JSON 模式(不太可能,它早就过时了),否则您应该使用 required 的数组形式。一些较旧的实现允许您使用这两种形式,但这不是一个好主意。您应该以单一规范为目标,而不是混合使用来自两个不同版本规范的关键字。

{
    "id": "/listEvents",
    "type": "object",
    "properties": {
        "filter": {
            "$ref": "/MarketFilter"
        },
        "locale": {
            "type": "string"
        }
    },
    "required": ["filter"]
}