首页 > 解决方案 > JSON Schema - 对象枚举

问题描述

我是 JSON 模式的新手,所以请耐心等待。我的目标是拥有一个作为对象的 JSON 属性。它的键相互关联,这意味着多个键始终具有相同的值。这可能有助于说明清楚,这是我尝试使用枚举来做到这一点:

{
  "$schema": "https://json-schema.org/draft/2019-09/schema",
  "title": "Part",
  "type": "object",
  "properties": {
    "relationship": {
      "type": "object",
      "enum": [
        {
          "code": "1",
          "value": "MEMBER"
        },
        {
          "code": "2",
          "value": "SPOUSE"
        },
        {
          "code": "3",
          "value": "CHILD"
        },
        {
          "code": "4",
          "value": "STUDENT"
        },
        {
          "code": "5",
          "value": "DISABILITY_DEPENDENT"
        },
        {
          "code": "6",
          "value": "ADULT_DEPENDENT"
        },
        {
          "code": "8",
          "value": "DOMESTIC_PARTNER"
        }
      ]
    }
  }
}

所以使用这样的枚举是可行的,即使我在 JSON Schema 规范中的任何地方都找不到它。但是,错误消息很糟糕。通常我会从模式验证中得到最详细的错误消息,但是在这种情况下我没有。

$.part.relationship: does not have a value in the enumeration [, , , , , , ]

我不确定我做错了什么。我正在为 JSON Schema 使用 Java 解析器:

<dependency>
    <groupId>com.networknt</groupId>
    <artifactId>json-schema-validator</artifactId>
    <version>1.0.53</version>
</dependency>

不确定错误消息是解析器的错误还是我对模式做的不好。帮助将不胜感激。

标签: javajsonjsonschema

解决方案


这对我来说是新闻,但根据规范,对象似乎是有效的枚举值。也就是说,你的用法很不寻常。我以前没见过它用过。

六种基本类型(“null”、“boolean”、“object”、“array”、“number”或“string”)...

6.1.2. 枚举 ...

数组中的元素可以是任何类型,包括 null。

您的问题基本上是您使用的库不知道如何将这些对象转换为可打印的字符串。即使它确实给了它一个合理的选择,你最终可能会得到

does not have a value in the enumeration [{"code": "1", "value":"MEMBER"}, {"code": "2" ...

这可能没问题,但这并不令人惊讶。如果代码和值都有效但不匹配,您可能需要仔细查看列表才能发现问题。

JSON Schema 通常不太擅长在它认为是 2 个不相关的字段之间强制执行约束。这超出了它的目标范围。它试图验证结构。字段之间的依赖关系是业务约束,而不是结构约束。

我认为要获得可读的错误消息,最好的办法是拥有 2 个子属性,每个子属性都有一个包含 8 个值的枚举;一个用于代码,一个用于值。

然后你会得到

$.part.relationship.code does not have a value in the enumeration [1,2,3,4 ...

或者

$.part.relationship.value does not have a value in the enumeration ["MEMBER", "SPOUSE", ...

如果强制执行该约束对您很重要,您可以在模式验证之上进行一些额外的业务验证。然后生成您自己的错误,例如

code "1" does not match value "SPOUSE"

推荐阅读