Mastering JSON Schema: From Basics to Advanced Features

Introduction

JSON Schema is a powerful tool that allows you to validate and define rules for your JSON data. Whether you're working with APIs, databases, or configuration files, creating a schema can ensure that your data is structured correctly. In this comprehensive blog post, we'll dive deep into the intricate workings of JSON Schema, starting from the fundamentals and progressing towards more advanced concepts. By the end, you'll have a solid understanding of JSON Schema and be equipped with the knowledge to create your very own schema based on your unique requirements.

What is JSON Schema?

JSON Schema is a vocabulary that allows you to annotate and validate JSON documents. It is a JSON document that defines the structure and constraints of another JSON document. It allows developers to specify the expected properties and their types, and to define additional constraints on the values of those properties.

To create a simple JSON Schema, you need to define the properties that are expected in the JSON document, along with their types and any additional constraints. Let's try to understand this with an example:

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "object",
  "properties": {
    "name": {
      "type": "string"
    },
    "age": {
      "type": "integer",
      "minimum": 0,
      "maximum": 110
    },
    "email": {
      "type": "string",
      "format": "email"
    }
  },
  "required": ["name", "age"]
}
  • The $schema property specifies the version of JSON Schema being used. In this case, we're using draft-07. (other drafts can be found here)
  • The type property specifies that the JSON document must be an object.
  • The properties object lists the expected properties and their types. In this case, we have three properties: name, age, and email. The name property must be a string, while the age property must be an integer between 0 and 150. The email property must be a string in email format.
  • The required array lists the properties that are required in the JSON document. In this case, both name and age are required.

Validating a JSON Document Against a Schema

Once you have defined a JSON Schema, you can use it to validate JSON documents. There are many JSON Schema validators available for different programming languages, and some of them can be found here. Here is an example of how to use Ajv to validate a JSON document against the above schema:

const Ajv = require("ajv");
const ajv = new Ajv();

const schema = {
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "object",
  "properties": {
    "name": {
      "type": "string"
    },
    "age": {
      "type": "integer",
      "minimum": 0,
      "maximum": 110
    },
    "email": {
      "type": "string",
      "format": "email"
    }
  },
  "required": ["name", "age"]
};

const data = {
  "name": "John Smith",
  "age": 30,
  "email": "john.smith@example.com"
};

const validate = ajv.compile(schema);
const valid = validate(data);

if (!valid) {
  console.log(validate.errors);
}

In this example, we define the same schema as before, and then define a JSON document that we want to validate against the schema. We then compile the schema using Ajv and use the resulting function to validate the document. If the document is not valid, Ajv will return an array of errors.

Advanced features of JSON Schema and how to implement them

In the previous section, we discussed the basics of JSON Schema and how to create a simple schema. In this section, we will explore the advanced features of JSON Schema and how to implement them.

1. Referring to Other Schemas

One of the advanced features of JSON Schema is the ability to refer to other schemas. This is useful when you have a complex JSON document with multiple nested objects and you want to reuse the same schema for each of them. To refer to another schema, you can use the $ref keyword. Here is an example:

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "object",
  "properties": {
    "name": {
      "type": "string"
    },
    "address": {
      "$ref": "#/definitions/address"
    }
  },
  "required": ["name", "address"],
  "definitions": {
    "address": {
      "type": "object",
      "properties": {
        "street": {
          "type": "string"
        },
        "city": {
          "type": "string"
        },
        "state": {
          "type": "string",
          "maxLength": 2
        }
      },
      "required": ["street", "city", "state"]
    }
  }
}

In this example, we define a schema for a person object that includes a nested address object. Instead of defining the address schema inline, we refer to it using the $ref keyword and a JSON Pointer. The definitions object lists all the schemas that can be referred to within the main schema.

2. Conditional Validation

JSON Schema also supports conditional validation, which allows you to specify different validation rules based on the values of certain properties. This is useful when you want to validate data based on a set of conditions. Here is an example:

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "object",
  "properties": {
    "type": {
      "type": "string",
      "enum": ["book", "movie"]
    },
    "title": {
      "type": "string"
    },
    "author": {
      "type": "string"
    },
    "director": {
      "type": "string"
    }
  },
  "if": {
    "properties": {
      "type": {
        "const": "book"
      }
    }
  },
  "then": {
    "required": ["title", "author"]
  },
  "else": {
    "required": ["title", "director"]
  }
}

In this example, we define a schema for a media object that can either be a book or a movie. We use the if, then, and else keywords to specify different validation rules based on the value of the type property. If the type property is set to book, then the title and author properties are required. If the type property is set to movie, then the title and director properties are required.

3. Combining Schemas

JSON Schema provides several keywords that allow you to combine multiple schemas into a single schema. This is useful when you want to validate a JSON document against multiple criteria. Here are some of the combining keywords:

  • allOf: requires the JSON document to validate against all of the given schemas
  • anyOf: requires the JSON document to validate against at least one of the given schemas
  • oneOf: requires the JSON document to validate against exactly one of the given schemas
  • not: requires the JSON document to not validate against the given schema

Here is an example that combines multiple schemas using the allOf keyword:

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "allOf": [
    {
      "type": "object",
      "properties": {
        "name": {
          "type": "string"
        }
      },
      "required": ["name"]
    },
    {
      "type": "object",
      "properties": {
        "age": {
          "type": "integer",
          "minimum": 18
        }
      },
      "required": ["age"]
    }
  ]
}

In this example, we define a schema that requires the JSON document to be an object with both a name property (that is a string and is required) and an age property (that is an integer and has a minimum value of 18).

These are just a few of the advanced features of JSON Schema and more features can be found here. By using these features, you can create powerful and flexible schemas that can validate complex JSON documents with ease.

Wrapping Up!

To summarize, JSON Schema is a useful vocabulary for annotating and validating JSON documents. It allows developers to define the structure and constraints of JSON data and specify the expected properties, their types, and any additional constraints. By using a JSON Schema validator, like Ajv, developers can ensure that their JSON documents conform to a specific schema, and any errors can be easily identified and fixed. Overall, JSON Schema is a valuable tool for improving the consistency and reliability of JSON data.

Thank you for taking the time to read this blog. I hope you found it informative and useful in your work with JSON data. Subscribe to my newsletter for more such informative content in the near future!

Peace!✌️