如何验证 child 属性 在 object 中的所有 children 中仅设置一次

How to validate that child property is set only once amongst all children in object

我正在尝试验证以下内容 JSON

{
    "domain": "example.com", 
    "docker": {
        "services": {
            "app": {
                "image": "nginxdemos/hello:latest", 
                "expose_port": 80,
                "volumes": [
                    "./:/test"
                ]
            }, 
            "db": {
                "image": "mariadb:10.5"
            }
        }
    }
}

我想确保 services children 里面的 expose_port 只能定义一次。因此,将 "expose_port": 1234 添加到 "db" 应该会使 JSON.

无效

这是我目前的架构:

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "$id": "http://saitho.me/project-configuration.schema.json",
  "title": "Project Configuration",
  "description": "Project configuration file",
  "type": "object",
  "definitions": {
    "docker-service": {
      "properties": {
        "image": {
          "description": "Name of Docker image",
          "type": "string"
        },
        "volumes": {
          "description": "Docker volumes to be mounted",
          "type": "array",
          "items": {
            "type": "string"
          },
          "minItems": 1
        }
      },
      "required": [ "image" ]
    }
  },
  "properties": {
    "domain": {
      "description": "The domain from which the app can be reached",
      "type": "string"
    },
    "docker": {
      "description": "Configuration for Docker containers that will be deployed",
      "type": "object",
      "properties": {
        "services": {
          "description": "List of Docker services to be started",
          "type": "object",
          "patternProperties": {
            ".*": {
              "$ref": "#/definitions/docker-service",
              "oneOf": [
                {
                      "properties": {
                        "expose_port": {
                          "description": "Port that receives web traffic (e.g. 80, 3000, 8080 for most applications). Only one in this file!",
                          "type": "integer"
                        }
                      }
                }
              ],
              "type": "object"
            }
          },
          "additionalProperties": false
        }
      },
      "required": [ "services" ]
    }
  },
  "required": [ "domain" ]
}

到目前为止,我已经尝试将 allOf 和 oneOf 结合使用,但这似乎只适用于当前 child 而不是同时查看兄弟姐妹。有谁知道我的问题的解决方案? :)

谢谢!

如果您有一组特定的服务(例如,暴露的端口只会在 "app" 或 "db" 上),您可以使用 "oneOf" 来测试那个两者中的一个有 属性(或两者都没有,作为第三次测试)。

如果您有任意一组服务,那么您将不再执行 "structural" 验证,而是进入业务逻辑领域。在这种情况下,每个值都可能取决于所有其他值的值。单独使用 JSON 架构验证无法验证这一点,请参阅页面 Scope of JSON Schema Validation 了解更多信息。

但是,您可以对 JSON 文档进行布局以匹配您要完成的任务。如果有一个 属性 只能定义一次,那么将 属性 定义分解到一个只能定义一次的地方:

{
    "domain": "example.com", 
    "docker": {
        "services": {
            "app": {
                "image": "nginxdemos/hello:latest", 
                "volumes": [
                    "./:/test"
                ]
            }, 
            "db": {
                "image": "mariadb:10.5"
            }
        },
        "expose_service": "app",
        "expose_port": 80
    }
}