How to create a valid definitions only jsonschema file?

Sometimes it is useful to group jsonschema to be referenced elsewhere when desired like a utility module but for schema.
However, it is a little confusing on how to group these definitions.
There is also the issue of making sure the schema is still valid because jsonschema libraries that handle things such as validation may not accept custom formats.

I asked Bard AI, and got an appropriate response, so I have shared the information below:

I want to create a jsonschema file that only contains definitions(jsonschema that can be referenced).
I don’t need the root object to be a usable schema.
I want the file to be a valid jsonschema.

Is this possible, and please provide an example.

Yes, it is possible to create a JSON schema file that only contains definitions. This is a perfectly valid way to use JSON schema, and it can be useful for organizing your schemas and making them more reusable.

Here is an example of a JSON schema file that only contains definitions:

JSON
{
  "$schema": "http://json-schema.org/draft/2020-12/schema",
  "definitions": {
    "MediaObject": {
      "type": "object",
      "required": ["type", "url"],
      "properties": {
        "type": {
          "type": "string",
          "enum": ["image/jpeg", "image/png"]
        },
        "url": {
          "type": "string",
          "format": "uri"
        }
      }
    },
    "Person": {
      "type": "object",
      "required": ["name", "age"],
      "properties": {
        "name": {
          "type": "string"
        },
        "age": {
          "type": "integer"
        }
      }
    }
  }
}

This schema file defines two schemas: MediaObject and Person. These schemas can then be referenced from other schema files using the $ref keyword.

For example, the following schema file references the MediaObject and Person schemas defined in the previous example:

JSON
{
  "$schema": "http://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "required": ["mediaObject", "person"],
  "properties": {
    "mediaObject": {
      "$ref": "#/components/schemas/MediaObject"
    },
    "person": {
      "$ref": "#/components/schemas/Person"
    }
  },
  "components": {
    "schemas": {
      "MediaObject": {
        "$ref": "#/definitions/MediaObject"
      },
      "Person": {
        "$ref": "#/definitions/Person"
      }
    }
  }
}

This schema file is valid, even though the root object is not a usable schema. This is because the root object is only used to define the MediaObject and Person schemas, which can then be referenced from other schema files.

You can use this approach to create a library of reusable schema definitions. This can make your schemas more modular and easier to maintain.

I was reading the jsonschema specification draft, and noticed that the “$defs” property was used to group definitions. I have noticed you and others have used the “definitions” property to group definitions. Which one is better, and why?

The $defs keyword was introduced in JSON Schema draft 2019-09. It is a newer and more standardized way to group definitions.

The definitions keyword is still valid, but it is deprecated. It is recommended that new schemas use the $defs keyword instead.

There are a few reasons why the $defs keyword is better:

  • It is more standardized. The definitions keyword was not defined in the JSON Schema specification, but was rather a convention that was widely used. The $defs keyword is defined in the JSON Schema specification, so it is more likely to be supported by all JSON schema implementations.
  • It is more explicit. The definitions keyword could be used for other purposes in addition to grouping definitions. For example, it could be used to define a set of named anchors for use in JSON Pointer expressions. The $defs keyword is specifically for grouping definitions, so it is more explicit and less likely to be confused with other features of JSON Schema.
  • It is more future-proof. The JSON Schema specification is still under development, and it is possible that the definitions keyword could be deprecated in the future. The $defs keyword is a newer keyword, so it is more likely to be supported in the future.

Overall, the $defs keyword is the better choice for grouping definitions in JSON Schema. It is more standardized, more explicit, and more future-proof.

However, it is important to note that the definitions keyword is still valid, and there are many existing JSON schemas that use it. If you are working with an existing JSON schema that uses the definitions keyword, there is no need to change it to use the $defs keyword.

As stated, if the root schema only provides the definitions, then it is valid, and although the “definitions” property is often used for grouping definitions, it has actually been standardized to be “$defs” instead, but definitions is still valid and has been used from before the property was standardized.