Removing the duplication in a JSON schema that uses oneOf (v4 or v5)

北城余情 提交于 2019-12-11 06:03:38

问题


I have a set of 2 properties that are always optional, but should only be allowed to be present if the value of another (always required) boolean property is true.

The properties which are always optional, but not always allowed are named: max_recurrences and recurrence_arguments. The boolean property whose value of true that they depend on is named: recurring.

I've come up with the schema below, which I think works, but I'm duplicating all of the other properties in each item of the oneOf array. I'm looking for a way to avoid this duplication.

{
  "id": "plan_schedule",
  "type": "object",
  "oneOf": [
    {
      "properties": {
        "start_date": {
          "type": "string",
          "format": "date-time"
        },
        "end_date": {
          "type": "string",
          "format": "date-time"
        },
        "trigger": {
          "$ref": "re_non_empty_string"
        },
        "arguments": {
          "type": "object",
          "minProperties": 1
        },
        "recurring": {
          "type": "boolean",
          "enum": [true],
        },
        "max_recurrences": {
          "type": "integer",
          "minimum": 1
        },
        "recurrence_arguments": {
          "type": "object",
          "minProperties": 1
        }
      }
    },
    {
      "properties": {
        "start_date": {
          "type": "string",
          "format": "date-time"
        },
        "end_date": {
          "type": "string",
          "format": "date-time"
        },
        "trigger": {
          "$ref": "re_non_empty_string"
        },
        "arguments": {
          "type": "object",
          "minProperties": 1
        },
        "recurring": {
          "type": "boolean",
          "enum": [false],
        },
      }
    }
  ],
  "additionalProperties": false,
  "required": ["start_date", "trigger", "recurring"]
}

Can anyone help me out? I'd like to use v4, but I'm open to using v5 if it helps.

To clarify further, I'm hoping to only have to list the properties: start_date, end_date, trigger and arguments one time in the entire schema.


回答1:


JSON Schema draft-04:

{
  "type": "object",
  "properties": {
    "recurring": {
      "type": "boolean"
    }
    // all other properties
  }
  "additionalProperties": false,
  "required": ["start_date", "trigger", "recurring"]
  "anyOf": [
    {
      "properties": { "recurring": { "enum": [true] } }
    },
    {
      "properties": { "recurring": { "enum": [false] } },
      "not": {
        "anyOf": [
          { "required": ["max_recurrences"] },
          { "required": ["recurrence_arguments"] }
        }
      }
    }
  ]
}

If you use Ajv (I assume so because v5 is the concept not used anywhere else) you can simplify the above using custom keywords "if/then/else" and "prohibited" that are proposed for draft-07 and have some support - they are defined in ajv-keywords. "anyOf" can be replaced with:

"if": { "properties": { "recurring": { "enum": [false] } } },
"then": { "prohibited": ["max_recurrences", "recurrence_arguments"] }

EDIT:

Actually, it can be done even simpler with "dependencies" keyword without any custom keywords. Instead of "anyOf":

"dependencies": {
  "max_recurrences": { "$ref": "#recurring" },
  "recurrence_arguments": { "$ref": "#recurring" }
},
"definitions": {
  "recurring": {
    "id": "#recurring",
    "properties": {
      "recurring": { "enum": [true] }
    }
  }
}


来源:https://stackoverflow.com/questions/41837518/removing-the-duplication-in-a-json-schema-that-uses-oneof-v4-or-v5

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!