Is it possible to have common properties before on

2019-09-12 02:20发布

I have this json schema that has an array that contains multiple object, and each object differs slightly from the others based on certain patterns.

Example.

[
  {
    "ID": "pgID",
    "Name": "John",
    "Surname": "Doe",
    "ProjectsInvolved": [
      "My Project",
      "My Project 2"
    ]
  },
  {
    "ID": "jtID",
    "Name": "John",
    "Surname": "Doe",
    "WorksOn": [
      "Monday",
      "Thursday"
    ]
  }
]

The json schema for that would be:

{
  "$schema": "http://json-schema.org/draft-04/schema",
  "type": "array",
  "items": {
    "oneOf": [
      {
        "type": "object",
        "properties": {
          "ID": {
            "type": "string",
            "pattern": "^(pg)\\w*$"
          },
          "Name": {
            "type": "string"
          },
          "Surname": {
            "type": "string"
          },
          "ProjectsInvolved": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        }
      },
      {
        "type": "object",
        "properties": {
          "ID": {
            "type": "string",
            "pattern": "^(jt)\\w*$"
          },
          "Name": {
            "type": "string"
          },
          "Surname": {
            "type": "string"
          },
          "WorksOn": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        }
      }
    ]
  },
  "additionalProperties": false
}

My issue is that although the real json is similar, it has many more items, and it is poised to grow larger as more time passes. Therefore I must ask, is it possible for the schema to group the identical elements Name, and Surname, and only have the ID and the arrays in the oneOf?

An Example of the suggested schema:

{
  "$schema": "http://json-schema.org/draft-04/schema",
  "type": "array",
  "items": {
    "type": "object",
    "properties": {
      "Name": {
        "type": "string"
      },
      "Surname": {
        "type": "string"
      },
      "oneOf": [
        {
          "ID": {
            "type": "string",
            "pattern": "^(pg)\\w*$"
          },
          "ProjectsInvolved": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        },
        {
          "ID": {
            "type": "string",
            "pattern": "^(jt)\\w*$"
          },
          "WorksOn": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        }
      ]
    }
  },
  "additionalProperties": false
}

1条回答
我命由我不由天
2楼-- · 2019-09-12 02:57

Generally, you want to define the common stuff upfront and the special conditions after. This makes the schema easier to read and results in better error messages.

In this example, if "ProjectsInvolved" is present, then "ID" must start with "pg" and "WorksOn" can not be present. And, if "WorksOn" is present, then "ID" must start with "jt" and "ProjectsInvolved" can not be present.

It is possible to something like this with oneOf or anyOf as well, but you generally get better error messaging with dependencies.

{
  "$schema": "http://json-schema.org/draft-04/schema",
  "type": "array",
  "items": {
    "type": "object",
    "properties": {
      "ID": { "type": "string" },
      "Name": { "type": "string" },
      "Surname": { "type": "string" },
      "ProjectsInvolved": {
        "type": "array",
        "items": { "type": "string" }
      },
      "WorksOn": {
        "type": "array",
        "items": { "type": "string" }
      }
    },
    "dependencies": {
      "ProjectsInvolved": {
        "properties": {
          "ID": { "pattern": "^(pg)\\w*$" }
        },
        "not": { "required": ["WorksOn"] }
      },
      "WorksOn": {
        "properties": {
          "ID": { "pattern": "^(jt)\\w*$" }
        },
        "not": { "required": ["ProjectsInvolved"] }
      }
    }
  },
  "additionalProperties": false
}
查看更多
登录 后发表回答