如何验证子属性在对象的所有子对象中仅设置一次

问题描述 投票:0回答:1

我正在尝试验证以下JSON

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

我想确保expose_port子级内的services只能定义一次。因此,将"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组合在一起,但这似乎仅对当前的孩子有效,而不是对同级的孩子进行检查。有人知道我的问题的解决方案吗? :)

谢谢!

json jsonschema json-schema-validator python-jsonschema
1个回答
0
投票

[如果您具有一组特定的服务(例如,公开的端口将仅位于“ app”或“ db”上,则可以使用“ oneOf”来测试两者中的一个是否具有属性(或都不具有) ,作为第三个测试)。

如果您拥有任意一组服务,那么您将不再执行“结构”验证,而是进入业务逻辑领域。在这种情况下,每个值都取决于可能所有其他值的值。仅通过JSON Schema验证无法进行验证,有关更多信息,请参见页面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
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.