Как проверить, что дочернее свойство установлено только один раз среди всех дочерних объектов в объекте - PullRequest
0 голосов
/ 11 апреля 2020

Я пытаюсь проверить следующее 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, но это Кажется, что он работает только над текущим ребенком, а не смотрит на братьев и сестер. Кто-нибудь знает решение моей проблемы? :)

Спасибо!

1 Ответ

1 голос
/ 12 апреля 2020

Если у вас есть определенный c набор сервисов (например, открытый порт будет когда-либо только в «app» или «db»), вы можете использовать «oneOf», чтобы проверить, что ровно один из двух имеет свойство (или ни одно, как третий тест).

Если у вас есть произвольный набор служб, то вы больше не выполняете «структурную» проверку, а переходите в область бизнес-логики c , В этом случае каждое значение зависит от значения потенциально всех других значений. Подтвердить это невозможно только с помощью JSON Проверка схемы. Дополнительные сведения см. На странице Область действия JSON Проверка схемы .

Однако вы можете оформить документ JSON чтобы соответствовать тому, что вы пытаетесь достичь sh. Если есть свойство, которое может быть определено только один раз, тогда выделите определение свойства в место, где оно может быть определено только один раз:

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