Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to use additionalProperties from a $ref file?

ive separated my JSON schemas into two files.

person-input.json (all properties that will be set by inputs.)

person.json (hold a ref to person-input.json but also have dateUpdate, dateCreated and DateDeleted).

This to separate the inputs from autogenerated date properties.

I do not want any posts to be able to add unwanted properties to my data, so i thought i would use "additionalProperties": false the problem is that if i use it in the person-input.json file it will not accept my "date" properties from the person.json file. And if i put it in the person.json file it doesn't stop random properties from being added. Is there a solution to this?

so this below dont work, have i missplaced the "additionalProperties": false ?

person.json

{
  "allOf": [
    {
      "$ref": "./person-input.json"
    },
    {
      "type": "object",
      "properties": {
        "dateCreated": {
        "name": "dateCreated",
        "type": "string",
        "description": "date created",
        "example": "2019-09-02T11:17:41.783Z"
        },
        "dateUpdated": {
          "type": "string",
          "nullable": true,
          "description": "date updated",
          "example": "2019-09-02T11:17:41.783Z"
        },
        "dateDeleted": {
          "type": "string",
          "nullable": true,
          "description": "date deleted",
          "example": "2019-09-02T11:17:41.783Z"
        }
      },
      "additionalProperties": false
    }
  ]
}
like image 313
csk87 Avatar asked Mar 03 '23 08:03

csk87


1 Answers

additionalProperties cannot "see through" applicators like allOf, nor can it "see across" the use of $ref.

In order to fix this, you have to do SOME duplication of your schema in your outer most / top most schema, and remove the additionalProperties: false requirement from any child schemas.

additionalProperties: false works by applying false (which is a valid schema, which returns failure to validate) to values which do not match keys based on properties or patternProperties within the SAME schema object.

Validation with "additionalProperties" applies only to the child
values of instance names that do not match any names in "properties", and do not match any regular expression in "patternProperties".

https://datatracker.ietf.org/doc/html/draft-handrews-json-schema-validation-01#section-6.5.6 (draft-7)

So, if you need to copy all the properties you need to the top level schema. Yes this is not nice!

You can make it a little nicer by observing the fact that the values of a properties object are schemas, and as such may just be true, allowing the child schemas to actually DO the validation later.

Here's an example I'm going to be using in an upcoming talk:

{
  "$schema": "http://json-schema.org/draft-07/schema",
  "title": "MatchMakerExchange format for queries",
  "definitions": {
    "phenotypicFeatures": {
      "type": [
        "array"
      ]
    },
    "genomicFeatures": {
      "type": [
        "array"
      ]
    },
    "geneticsPatient": {
      "properties": {
        "phenotypicFeatures": {
          "$ref": "#/definitions/phenotypicFeatures"
        },
        "genomicFeatures": {
          "$ref": "#/definitions/genomicFeatures"
        }
      },
      "anyOf": [
        {
          "required": [
            "phenotypicFeatures"
          ]
        },
        {
          "required": [
            "genomicFeatures"
          ]
        }
      ]
    },
    "regularPatient": {
      "type": "object",
      "required": [
        "name"
      ],
      "properties": {
        "name": {
          "type": [
            "string"
          ]
        }
      }
    }
  },
  "properties": {
    "patient": {
      "additionalProperties": false,
      "properties": {
        "name": true,
        "phenotypicFeatures": true,
        "genomicFeatures": true
      },
      "allOf": [
        {
          "$ref": "#/definitions/regularPatient"
        },
        {
          "$ref": "#/definitions/geneticsPatient"
        }
      ]
    }
  }
}

You may well ask... "Well, that's crazy. Can you fix this please?" - We did. It's called draft 2019-09, and it's only recently been released, so you'll have to wait for implementations to catch up.

A new keyword, unevaluatedProperties depends on annotation results, but you'd still need to remove additionalProperties: false from child schemas.

like image 145
Relequestual Avatar answered Mar 16 '23 02:03

Relequestual