JSON 接受的有效负载与返回的对象的架构

JSON schema for payloads accepted vs objects returned

我正在充实 RESTful Web 服务的模式,但我在一件小事上有点难过。想象一下,如果我有以下模式:

{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "required": ["name"],
  "properties": {
    "name": {
      "type": "string"
    },
    "urn": {
      "type": "string"
    }
  }
}

由于 URN 是由我的服务生成的,所以我不想在客户端请求中接受它。所以 urn 不包含在 required 数组中。但是,它在响应中是必需的,因此我无法使用此架构来验证我的服务提供的响应。我宁愿不必使用两种不同的架构,也不必让它们保持同步。

有没有一种方法可以使用单一模式对两种情况进行严格建模?或者,如果我需要使用两个模式,是否有一种方法可以引用一个通用的结构模式并仅覆盖我的请求和响应模式中的 required 字段?

您可以通过使用“oneOf”来使用动态模式

{
    "type" : "object",
    "required" : ["name"],
    "properties" : {
        "name" : {
            "oneOf" : [{
                    "$ref" : "#/definitions/withURN"
                }, {
                    "$ref" : "#/definitions/withoutURN"
                }
            ]
        }
    },
    "definitions" : {
        "withURN" : {
            "properties" : {
                "name" : {
                    "type" : "string"
                },
                "urn" : {
                    "type" : "string"
                }
            }
        },
        "withoutURN" : {
            "properties" : {
                "name" : {
                    "type" : "string"
                }
            }
        }
    }
}

看一些例子:http://json-schema.org/example2.html

还有这个讨论帖:How to use dependencies in JSON schema (draft-04)

这是一个已知问题,没有好的处理方法。

将其保留为一个模式的唯一方法是不在 required 数组中包含服务器生成的属性,并在服务器端进行额外检查以验证这些属性。

不,无法覆盖架构关键字。 JSON 模式关键字总是向集合添加约束。您需要从通用模式开始,然后使用 allOf.

从那里扩展

这是您需要做的事情的示例。

创建模式:

{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "id": "http://example.com/create-my-schema",
  "type": "object",
  "required": ["name"]
  "properties": {
    "name": {
      "type": "string"
    }
  }
}

完整架构:

{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "id": "http://example.com/my-schema",
  "allOf": [{ "$ref": "http://example.com/create-my-schema" }],
  "required": ["urn"],
  "properties": {
    "urn": {
      "type": "string"
    }
  }
}

如果您不关心模式的人类可读性,这种方法很好。否则,有些人选择在服务器端动态构建模式,因此生成的模式可能有重复,但代码没有。