0

我正在尝试验证以下 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 结合起来,但这似乎只适用于当前的孩子,而不是看兄弟姐妹。有谁知道我的问题的解决方案?:)

谢谢!

4

1 回答 1

1

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

如果您有任意一组服务,那么您将不再执行“结构”验证,而是进入业务逻辑领域。在这种情况下,每个值都可能依赖于所有其他值的值。仅使用 JSON 模式验证无法验证这一点,有关更多信息,请参阅页面JSON 模式验证的范围。

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

{
    "domain": "example.com", 
    "docker": {
        "services": {
            "app": {
                "image": "nginxdemos/hello:latest", 
                "volumes": [
                    "./:/test"
                ]
            }, 
            "db": {
                "image": "mariadb:10.5"
            }
        },
        "expose_service": "app",
        "expose_port": 80
    }
}
于 2020-04-12T01:33:54.457 回答