【问题标题】:JSON Schema: represent constraint to encode object type in string typeJSON Schema:表示以字符串类型编码对象类型的约束
【发布时间】:2023-03-15 15:59:01
【问题描述】:

在我的 JSON 序列化数据中,我有嵌套对象:

{
  "A" : { "A1": 1,
          "A2": 2 },
  "B" : { "B1": 3,
          "B2": 4 }
}

由于我无法影响给定的限制,我需要将结构变平。这意味着,深度大于 1 的每个对象都必须编码为字符串。应用在上面的例子中会是这样的:

{
  "A" : "\{\"A1\": 1, \"A2\": 2\}"
  "B" : "\{\"B1\": 3, \"B2\": 4\}"  
}

因为我需要在JSON Schema 中表达这个约束,所以我几乎受其语法规则的约束。我猜这些对象的类型要么是string,要么是object

{
  "title": "My Schema",
  "type": "object",
  "properties": {

    "A": {
      "type": "string vs. object" 
    "B": {
      "type": "string vs. object"
}

【问题讨论】:

  • 我不认为你可以把它算作一个字符串,因为它就是这样。

标签: javascript json schema schema-design jsonschema


【解决方案1】:

我知道你已经选择了一个答案,但我想我只是在这里提一下工作原理。

JSON Schema 试图避免进行“语义”验证——也就是说,它们意味着验证标量类型中的数据(例如强制字符串格式或数值精度)。

如果您想像这样记录字符串值的内部格式,您可以使用"format" 值(可能是自定义值,因为标准中没有合适的值)。

...或者您可以使用"media"。这个模式关键字的值是一个对象,它可以有一个属性"type",它为字符串值指定一个媒体类型。所以你的属性看起来像:

{
    "type": "string",
    "media": {
        "type": "application/json"
    }
}

允许验证器忽略"format",并且极不可能使用"media" 进行验证(甚至没有直接提及),但就描述扁平化数据格式而言,"media"是最准确的方法。

(但是,正如公认的答案所述,将其视为一种奇怪的序列化方法而不是数据约束在许多方面是一种更优雅的解决方案)。

【讨论】:

  • 非常感谢您的回答,它为解决问题提供了很好的提示和附加信息。
【解决方案2】:

我同意,您可以选择objectstring 类型。我查看了JSON Schema documentation,但找不到任何可以根据需要清楚地表达约束的内容。因此,我想到了对这两种方法的简短讨论。

输入字符串

JSON Schema 定义了七种原始类型,包括对象。字符串被简单地定义为 JSON 字符串。 RFC 4627 将 JSON 字符串定义如下

字符串是零个或多个 Unicode 字符的序列

这将适用于您的情况,即使必须限制字符串的内容。问题是如何传达限制。我会使用description 来引用另一个子模式。您甚至可以为字符串定义pattern,并将子模式编码为正则表达式。然而,这将非常容易出错并且根本不可读。但是,它可以用于更好地验证数据的模式。

{
  "title": "My Schema",
  "type": "object",
  "properties": {

    "A": {
      "type": "string".
      "description": "Please refer to http://... for the subschema."
    },
    "B": {
      "type": "string"
      "description": "Please refer to http://... for the subschema."
    }
}

这样做的好处是,很明显 JSON 提供程序必须将字符串放入该属性中。缺点是不能将完整的模式视为一次,描述可能会被监督,查找过程也很麻烦。最后看到类型 string 但在子模式中定义了 object 时会非常混乱。

类型对象

通过简单地使用类型,您可以避免使用字符串的所有缺点。这里的问题实际上是,说明必须是字符串编码的描述将被忽略。

{
  "title": "My Schema",
  "type": "object",
  "properties": {

    "A": {
      "description": "Must be encoded as string",
      "type": "object",
      "properties": { "A1": { "type": "string" }, "A2": { "type": "string" } }
    },
    "B": {
      "description": "Must be encoded as string",
      "type": "object"
      "properties": { "A1": { "type": "string" }, "A2": { "type": "string" } }
    }
}

您总是可以完全伪造一些东西,例如使用类型 string 并为其定义 properties,但这将是无效的 JSON Schema。


我建议您使用 Type Object 方法。虽然使用字符串类型存在这种约束,但总是会导致其背后的数据降级。可以通过其他方式强制执行约束。观察谁提供数据,向各方传达约束,阻止与此约束相关的无效数据等。

谁知道呢,也许这个约束不会永远存在,如果这种情况发生变化,您需要再次更改架构,否则您只需要删除说明字符串编码要求的注释。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-30
    • 1970-01-01
    • 2019-10-15
    • 1970-01-01
    • 2011-01-17
    • 1970-01-01
    相关资源
    最近更新 更多