Alok
Alok

Reputation: 98

Validate JSON Schema with another JSON Schema

I am trying to validate JSON Schema using another JSON Schema.

Example of JSON Schema to validate: https://jsonschema.net/home

Reference of Validation schema to validate above schema: https://github.com/ajv-validator/ajv/blob/master/lib/refs/json-schema-draft-07.json

I have a requirement where property can only be of primitive type i.e string, number, integer, boolean. Since the root of JSON schema should have type as object and all the properties inside it will have type as primitive type, I am not sure how should I define type definition that validates the type at root level as object while type inside properties as primitive type.

Sample JSON:

{
    "$schema": "http://json-schema.org/draft-07/schema",
    "$id": "http://example.com/example.json",
    "type": "object",
    "title": "The root schema",
    "description": "The root schema comprises the entire JSON document.",
    "default": {},
    "examples": [
        {
            "name": "A green door"
        }
    ],
    "required": [
        "name"
    ],
    "properties": {
        "name": {
            "$id": "#/properties/name",
            "type": "string",
            "title": "The name schema",
            "description": "An explanation about the purpose of this instance.",
            "default": "",
            "examples": [
                "A green door"
            ]
        }
    },
    "additionalProperties": true
}

Validation JSON that validates the type:

  definitions: {
    simpleTypes: {
      enum: ['array', 'boolean', 'integer', 'null', 'number', 'object', 'string'],
    }
  },
  properties: {
  type: {
      anyOf: [
        { $ref: '#/definitions/simpleTypes' },
      ],
    },
  }

From the above simpleTypes -> enum if I remove object, my JSON becomes invalid.

Any way I can define enum for root type as different from type present inside properties?

Upvotes: 0

Views: 1217

Answers (1)

Jason Desrosiers
Jason Desrosiers

Reputation: 24399

Start by making a copy of the draft-07 schema and give it a unique $id.

{
  "$schema": "http://json-schema.org/draft-07/schema",
  "$id": "https://example.com/my-custom-draft-07-schema",
  "definitions": {
    ...original-definitions...
  },
  ...original-schema...
}

Since you want different constraints for schemas in different places, you'll need to refactor the schema to a definition so it can be referenced and extended for different situations. Don't forget to change all the recursive references ({ "$ref": "#" }) to point to the definition you created ({ "$ref": "#/definitions/schema" }).

{
  "$schema": "http://json-schema.org/draft-07/schema",
  "$id": "https://example.com/my-custom-draft-07-schema",
  "alllOf": [{ "$ref": "#/definitions/schema" }],
  "definitions": {
    ...original-definitions-with-modified-$refs...
   "schema": {
      ...original-schema-with-modified-$refs...
    }
  }
}

Next you'll need to add another definition specific to property schemas and change the $refs for property schemas to use the definition that was created ({ "$ref": "#/definitions/property-schema" }). Don't forget to change patternProperties and additionalProperties as well as properties. Other keywords, such as anyOf should continue to reference the generic schema ({ "$ref": "#/definitions/schema" }).

{
  "$schema": "http://json-schema.org/draft-07/schema",
  "$id": "https://example.com/my-custom-draft-07-schema",
  "alllOf": [{ "$ref": "#/definitions/schema" }],
  "definitions": {
    ...original-definitions-with-modified-$refs...
    "schema": {
      ...original-schema-with-modified-$refs...
    },
    "property-schema": {
      "allOf": [{ "$ref": "#/definitions/schema" }]
    }
  }
}

At this point, the schema has just been refactored. None of the behavior has changed except that you now have a place to put your custom constraints so they will only apply where you want them to. It should be relatively straightforward to add your constraints from here.

{
  "$schema": "http://json-schema.org/draft-07/schema",
  "$id": "https://example.com/my-custom-draft-07-schema",
  "alllOf": [{ "$ref": "#/definitions/schema" }],
  ...add-root-schema-constraints-here...
  "definitions": {
    ...original-definitions-with-modified-$refs...
    "schema": {
      ...original-schema-with-modified-$refs...
      ...add-global-constraints-here...
    },
    "property-schema": {
      "allOf": [{ "$ref": "#/definitions/schema" }]
      ...add-property-schema-constraints-here...
    }
  }
}

Upvotes: 2

Related Questions