Структура свойств Json зависит от другого свойства - PullRequest
0 голосов
/ 09 мая 2018

Я работал над схемой json, чтобы проверить ответы от одного из моих веб-сервисов.

Ответ разбит на два свойства: data и status. Если status.code установлен в 0, тогда data должен будет соблюдать определенную схему. Иначе, если status.code установлено в -1, data не будет прочитано, поэтому я не хочу проверять, соответствует ли оно схеме.

Вот схема:

{
    "$schema": "http://json-schema.org/schema#",
    "id": "file://registration.json",
    "type": "object",
    "properties": {
        "status": {
            "$ref": "#/definitions/classes/status"
        }
    },
    "anyOf": [
        {
            "$ref": "#/definitions/conditions/status-is-ok"
        },
        {
            "$ref": "#/definitions/conditions/status-is-nok"
        }
    ],
    "definitions": {
        "classes": {
            "status": {
                "type": "object",
                "properties": {
                    "code": {
                        "type": "integer"
                    },
                    "message": {
                        "type": "string"
                    }
                },
                "required": [
                    "code",
                    "message"
                ]
            },
            "data": {
                "type": "object",
                "properties": {
                    "propertyA": {
                        "type": "#/definitions/classes/metadatauser"
                    },
                    "propertyB": {
                        "type": "#/definitions/classes/membreinfo"
                    }
                },
                "required": ["propertyA", "propertyB"]
            }
        },
        "conditions": {
            "status-is-ok": {
                "status": {
                    "properties": {
                        "code": 0
                    }
                },
                "data": {
                    "$ref": "#/definitions/classes/data"
                }
            },
            "status-is-nok": {
                "status": {
                    "properties": {
                        "code": -1
                    }
                },
                "data": {
                    "type": "object"
                }
            }
        }
    }
}

А вот пример того, что не следует проверять:

{
    "data": {},
    "status": {
        "code": 0,
        "message": "OK"
    }
}

В данный момент эта часть кода проходит, и я не знаю почему.

1 Ответ

0 голосов
/ 09 мая 2018

У вас здесь несколько вещей не так, поэтому я постараюсь объяснить все из них. Вы были на правильном пути!

"properties": {
    "code": 0
}

Значение «свойств» ДОЛЖНО быть объектом. Каждое значение этого объекта ДОЛЖНА быть действительной схемой JSON.

http://json -schema.org / последний / JSON-схемы-validation.html # rfc.section.6.5.4

Вы не можете поместить ожидаемое вами значение в качестве значения ключа свойства. Однако вы МОЖЕТЕ использовать ключевое слово [const][1] для достижения проверки определенного значения.

"$ref": "#/definitions/conditions/status-is-ok"
...
"conditions": {
  "status-is-ok": {
    "status": {
      "properties": {

[Ключевое слово definitions] ДОЛЖНО быть объектом. Значение каждого члена этого
объект ДОЛЖЕН быть допустимой JSON-схемой.

https://tools.ietf.org/html/draft-handrews-json-schema-validation-01#section-9

Это означает, что вам нужно обрабатывать каждое значение каждого ключа в определениях как схему JSON. Если у вас была схема JSON, в которой вы не вкладывали «статус» в объект properties, проверка не проводилась. То же самое относится и к «данным».

(Строго говоря, в соответствии с разделом определений спецификации, вы НЕ ДОЛЖНЫ вкладывать схемы глубоко в объект определения, но в любом случае это поддерживается некоторыми реализациями и разрешается с использованием правильных правил разрешения. Префикс может быть лучше. )

Полная фиксированная схема выглядит следующим образом.

{
  "$schema": "http://json-schema.org/schema#",
  "id": "file://registration.json",
  "type": "object",
  "properties": {
    "status": {
      "$ref": "#/definitions/classes/status"
    }
  },
  "anyOf": [
    {
      "$ref": "#/definitions/conditions/status-is-ok"
    },
    {
      "$ref": "#/definitions/conditions/status-is-nok"
    }
  ],
  "definitions": {
    "classes": {
      "status": {
        "type": "object",
        "properties": {
          "code": {
            "type": "integer"
          },
          "message": {
            "type": "string"
          }
        },
        "required": [
          "code",
          "message"
        ]
      },
      "data": {
        "type": "object",
        "properties": {
        },
        "required": [
          "propertyA",
          "propertyB"
        ]
      }
    },
    "conditions": {
      "status-is-ok": {
        "properties": {
          "status": {
            "properties": {
              "code": {
                "const": 0
              }
            }
          },
          "data": {
            "$ref": "#/definitions/classes/data"
          },
        },
        "additionalProperties": false
      },
      "status-is-nok": {
        "properties": {
          "status": {
            "properties": {
              "code": {
                "const": -1
              }
            }
          },
          "data": {
            "type": "object"
          },
        },
        "additionalProperties": false
      }
    }
  }
}

Пожалуйста, дайте мне знать, если что-то из этого не имеет смысла. Не стесняйтесь присоединиться к слабому серверу JSON Schema, если хотите обсудить какие-либо аспекты дальше! Рад также комментировать здесь.

...