2022-09-21

Json Schema Refs - Use of Additional Properties or Unevaluated properties unclear

I have many objects which have the following properties which occur in multiple places. Unfortunately, they are not mapped to a specific property but only occur in the body of the JSON object like this: I want to be able to refer to this as a reference but without a specific property as I receive this as such from another application, Is there a way to do this? If you notice I have included a simple case where a person can have a title and occupation and a player can also have an occupation. However, an employee can also have a title and occupation. Since this is common to the person and employee, I want to be able to not repeat the title and occupation fields but just reference them by using the info definition like "$ref" like I did for combining a person and their football team using allOf. Another thing that does not work is unevaluatedProperties: false, which does not prevent someone from adding fields not in person or football_team. Using additionalProperties simply restricts it even more. In the sample json, party_affiliation should not be allowed.

person { 
  name,
  age,
  occupation,
  ... other properties
}

Because these properties occur in many objects, I created a definition called common. However, I am unable to use this as a reference in the body of the JSON as a reference. It seems there is no way to do so using something like "$ref": "#/definitions"/common-feature"

{
  "$defs": {
    "common": {
      "type": "object",
      "properties": {
        "title": {
          "type": "string"
        },
        "occupation": {
          "type": "string",
          "enum": ["Accountant", "Doctor", "Lawyer", "Director"]
        }
      }
    },
    "person": {
      "type": "object",
      "required": ["first_name", "last_name", "age"],
      "$ref": "#/$defs/common",
      "properties": {
        "first_name": {"type": "string"},
        "last_name": {"type": "string"},
        "age": {"type": "integer"}
      }
    },
    "employee": {
      "$ref": "#/$defs/common",
      "properties": {"name": {"type": "string"},
        "surname": {"type": "string"},
        "age": {"type": "integer"}
      }
    },
    "football_team": {
      "type": "object",
      "required": ["name", "league"],
      "properties": {
        "name": {"type": "string"},
        "league": {"type": "string"},
        "year_founded": {"type": "integer"}
      }
    }
  },

  "allOf": [
    {"$ref":  "#/$defs/person"},
    {"$ref":  "#/$defs/football_team"}
  ]
}

These JSON documents should be invalid but they are not, so the schema does not fulfill the intended purpose. Additional properties can be added and the references do not work as I set the occupation to something not in the enumeration.

{
  "first_name": "Sean",
  "last_name": "Damon",
  "age": 21,
  "name": "Brady",
  "league": "Braonfy",
  "party_affiliation" :"independent"
}

or this, which should be invalid:

{
  "first_name": "Davey",
  "last_name": "Mulch",
  "age": 21,
  "league": "Grody",
  "name": "Pullis",
  "science": "danihs",
  "title": "Dee",
  "occupation": "Master"
}


No comments:

Post a Comment