Skip to content
Writing
100% Human-Written

JSON Schema Examples Tutorial

June 23, 202115 min read
Technical
This is my original tutorial, republished on this website. The examples are preserved. Tool versions and interfaces may have changed.
JavaScript Object Notation (JSON) is a simple and lightweight data representational format. And, whenever we talk about data format we also talk about the schema because without a schema, data could mean anything. Let’s take an example.
{
  "id": 007,
  "name": "John Doe",
  "age": 22,
  "hobbies": {
        "indoor": [
            "Chess"
        ],
        "outdoor": [
            "Stand-up Comedy"
        ]
    }
}
If you were to look at the above example, you would not necessarily know if id can be zero (0). You would also not know if you could leave age blank. For this reason, we need to have metadata that holds information about valid data types and the description of the keys. And, JSON Schema gives you a standard way to structure the metadata.
JSON Schema is a proposed IETF standard for an outline or a model representing how a data should be formatted in JSON. Creating such standards for a JSON document lets you enforce consistency and data validity across similar JSON documents.
Let’s look at an example of a JSON Schema for the above data.
{
    "$schema": "http://json-schema.org/draft-04/schema#",
    "$id": "https://example.com/employee.schema.json",
    "title": "Record of employee",
    "description": "This document records the details of an employee",
    "type": "object",
    "properties": {
        "id": {
            "description": "A unique identifier for an employee",
            "type": "string"
        },
        "name": {
            "description": "Full name of the employee",
            "type": "string"
        },
        "age": {
            "description": "Age of the employee",
            "type": "number",
            "minimum": 16
        },
        "hobbies": {
            "description": "Hobbies of the employee",
            "type": "object",
            "properties": {
                "indoor": {
                    "type": "array",
                    "items": {
                        "description": "Enter the first hobby",
                        "type": "string"
                    },
                    "minItems": 1,
                    "uniqueItems": true
                },
                "outdoor": {
                    "type": "array",
                    "items": {
                        "description": "Enter the first hobby",
                        "type": "string"
                    },
                    "minItems": 1,
                    "uniqueItems": true
                }
            },
            "required": [
                "indoor",
                "outdoor"
            ]
        }
    },
    "required": [
        "id",
        "name",
        "age",
        "hobbies"
    ]
}
Looks daunting? Let’s break it down to understand further.
We have different keywords that are used in the above example. The following list explains what each of these keywords mean.
  • $schema: states that this schema is written according to the draft v4 specification.
  • $id: Defines the base URI to resolve other URI references within the schema.
  • title: Describes the intent of the schema.
  • description: Gives the description of the schema.
  • type: Defines the type of data.
  • properties: Defines various keys and their value types within a JSON document.
  • minimum: Defines the minimum acceptable value for a numeric datatype.
  • items: Enumerates the definition for the items that can appear in an array.
  • minItems: Defines the minimum number of items that should appear in an array.
  • uniqueItems: Enforces if every item in the array should be unique relative to one another.
  • required: Lists the keys that are required and mandatory.
For a full list of keywords, check out json-schema.org. It explains the keywords that you can use in your schema and their purpose.
MongoDB Atlas is a cloud-based managed document database that stores data in BSON format over the network. Confused? BSON is actually a very close cousin of JSON. It is a binary encoding of JSON-like documents that natively supports more data types than in pure JSON. But does that mean you can’t say MongoDB Atlas is a JSON database? No. Anything you can represent in JSON can be natively stored in MongoDB and retrieved as easily in JSON.
If you have already familiarized yourself with the JSON schema keywords and properties, we can jump right into starting a basic JSON schema. Lets begin with five basic keywords to define a person.
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://example.com/product.schema.json",
  "title": "Record of Employee",
  "description": "This document records the details of an employee",
  "type": "object"
}
In the above example, $schema links to the resource that identifies the dialect and the valid schemas written for this dialect. $id keyword identifies the schema resource. Here are a couple of things to know about this keyword:
  • The URI in this keyword is an identifier and not necessarily a network locator.
  • It must be a string.
  • It must represent a valid URI reference that is normalized and resolves absolute URI.
  • It must not contain a non-empty fragment.
  • It should not contain an empty fragment.
title keyword gives a short description of the schema and you can use the description keyword to explain more about the schema. In the above example, the title hints that this schema is about a record of an employee and the description explains that in detail. type keyword explains the valid data type of a record. In the above example, type sets the constraint for this document and tells us that this record is an object.
The schema that we have used in the above section is a basic outline. So, obviously we would like to add more properties to it so that the document answers further keys that will be used in the document. Let's first start by adding an id field to the employee record.
{
    "$schema": "http://json-schema.org/draft-04/schema#",
    "$id": "https://example.com/employee.schema.json",
    "title": "Record of employee",
    "description": "This document records the details of an employee",
    "type": "object",
    "properties": {
        "id": {
            "description": "A unique identifier for an employee",
            "type": "string"
        }
    }
}
Pretty simple and straightforward. You can see we are slowly building our schema by adding properties to validate the JSON documents. Let's do the same for name and age. But this time, we will also use required and minimum keywords.
{
    "$schema": "http://json-schema.org/draft-04/schema#",
    "$id": "https://example.com/employee.schema.json",
    "title": "Record of employee",
    "description": "This document records the details of an employee",
    "type": "object",
    "properties": {
        "id": {
            "description": "A unique identifier for an employee",
            "type": "string"
        },
        "name": {
            "description": "full name of the employee",
            "type": "string"
        },
        "age": {
            "description": "age of the employee",
            "type": "number",
            "minimum": 16
        }
    },
    "required": [
        "id"  
        "fullName",
        "age"
    ]
}
In the age property, we have used the minimum keyword to ensure that the age of the employee exceeds 16 everytime. We have also used the required keyword to define the mandatory properties. Let’s take it a step further and add an object inside the employee object.
To add an object inside an object in JSON format, we use nested data structure. Nested objects work quite similarly to the root object. You can use all the keywords that you used when defining the root object except for $schema and $id. They only have to be stated at the beginning of the schema. The following example shows how we can create an object within an object that takes array type data. In this example, we will use a few new keywords in addition to the ones we have already used.
{
    "$schema": "http://json-schema.org/draft-04/schema#",
    "$id": "https://example.com/employee.schema.json",
    "title": "Record of employee",
    "description": "This document records the details of an employee",
    "type": "object",
    "properties": {
        "id": {
            "description": "A unique identifier for an employee",
            "type": "string"
        },
        "name": {
            "description": "name of the employee",
            "type": "string"
        },
        "age": {
            "description": "age of the employee",
            "type": "number",
            "minimum": 16
        },
        "hobbies": {
            "description": "hobbies of the employee",
            "type": "object",
            "properties": {
                "indoor": {
                    "type": "array",
                    "items": {
                        "description": "Enter your hobby",
                        "type": "string"
                    },
                    "minItems": 1,
                    "uniqueItems": true
                },
                "outdoor": {
                    "type": "array",
                    "items": {
                        "description": "Enter your hobby",
                        "type": "string"
                    },
                    "minItems": 1,
                    "uniqueItems": true
                }
            },
            "required": [
                "indoor",
                "outdoor"
            ]
        }
    },
    "required": [
        "id",
        "fullName",
        "age",
        "hobbies"
    ],
 "additionalProperties": false
}
In the above example, we have defined two arrays - indoor and outdoor. You might have noticed the items keyword. This keyword defines the properties of each item within an array. Similarly, minItems keyword defines the minimum number of items that must be present in the array and uniqueItems keyword tells us if the items in the array are unique relative to each other. You will also see the required keyword again within the subobject. Like the required keyword in the root object, the required keyword within the subobject dictates the mandatory properties within the subobjects.
Lastly, we have also introduced the additionalProperties keyword. In the above example, it is a boolean taking the value false and is telling us that we can not use any other properties that are not listed under the properties keyword.
However, additionalProperties don’t necessarily have to be a boolean. It can also be an object. For example, in the schema below, this keyword is stating that any additional property that we use under this schema has to be a string.
"additionalProperties": { "type": "string" }
MongoDB Atlas is well suited to handle JSON formatted data interchange over the network. You can use MongoDB Atlas to create a free cluster where you can set up the database for your application. And since MongoDB stores the data in BSON, you can easily store and retrieve all your data in JSON format. After that, you can get started with using your JSON schema to validate the JSON files stored in the database. You can easily set validation rules by following the documentation on setting validation rules for your schema. You can use the $jsonSchema operator to match documents that satisfy the specified JSON Schema.The MongoDB JSON schema documentation is a good resource to get you up and running this operator. To learn more about MongoDB Atlas, refer to this article.
Though the above example is limited to a use case, there is limitless use of JSON schema. One of the areas where JSON schema can be used to validate and enforce consistency is with geographical coordinates. Because of the nature of the data, there is a high chance of accepting invalid or inconsistent data. In the example below, we can see that coordinates are represented using numeric data types.
{
  "latitude": 58.858093,
  "longitude": 22.294694
}
But there is a limit to the value that we can use for a coordinate i.e., the values cannot be more than 90 or less than negative 90. So let’s create a JSON schema to address this scenario.
{
  "$id": "https://example.com/geographical-location.schema.json",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "title": "Longitude and Latitude Values",
  "description": "A geographical coordinate.",
  "required": [ "latitude", "longitude" ],
  "type": "object",
  "properties": {
    "latitude": {
      "type": "number",
      "minimum": -90,
      "maximum": 90
    },
    "longitude": {
      "type": "number",
      "minimum": -180,
      "maximum": 180
    }
  }
}
Here you can see that we have used the minimum and maximum keyword for each property to limit the range of acceptable values. This not only resolves the issue with data validation but also ensures that incorrect values do not get through.
By now, we should have a pretty solid understanding of the JSON schema, why it is used and how we can use it. We have certainly expanded on the concept and how you can use it with MongoDB but there is more to cover. If you want to uncover more about JSON schema with MongoDB, we recommend you to go through MongoDB JSON schema validation resource. If you are interested in knowing more about JSON schema validation generally, check this article out.
JSON is a lightweight and easy-to-read data representational format used for storing and transporting data. It stands for JavaScript Object Notation. An example of storing an employee’s information in JSON is given below.
{
    "id": "007",
    "fullName": "John Doe",
    "age": 22,
    "position": "Web Developer",
    "company": "MongoDB",
    "hobbies": {
        "indoor": [
            "Chess"
        ],
        "outdoor": [
            "Stand-up Comedy"
        ]
    }
}
JSON schema is the representation of JSON in the form of an outline or model. By defining how other JSON documents should be, it sets the standard for other JSON documents.
Let’s look at an example of a JSON Schema for the JSON file given above.
{
    "$schema": "http://json-schema.org/draft-04/schema#",
    "$id": "https://example.com/employee.schema.json",
    "title": "Record of employee",
    "description": "This document records the details of an employee",
    "type": "object",
    "properties": {
        "id": {
            "description": "A unique identifier for an employee",
            "type": "string"
        },
        "fullName": {
            "description": "fullname of a person",
            "type": "string"
        },
        "age": {
            "description": "age of a person",
            "type": "number",
            "minimum": 16
        },
        "position": {
            "description": "position of a person",
            "type": "string"
        },
        "company": {
            "description": "the name of the company where the person works",
            "type": "string"
        },
        "hobbies": {
            "description": "hobbies of the person",
            "type": "object",
            "properties": {
                "indoor": {
                    "type": "array",
                    "items": {
                        "description": "Enter the first hobby",
                        "type": "string"
                    },
                    "minItems": 1,
                    "uniqueItems": true
                },
                "outdoor": {
                    "type": "array",
                    "items": {
                        "description": "Enter the first hobby",
                        "type": "string"
                    },
                    "minItems": 1,
                    "uniqueItems": true
                }
            },
            "required": [
                "indoor",
                "outdoor"
            ]
        }
    },
    "required": [
        "id",
        "fullName",
        "age",
        "position",
        "company",
        "hobbies"
    ]
}
This can seem a bit daunting. Let’s break it down and understand further.
We have different keywords that are used in the example given above. Let’s understand them.
  • $schema: This keyword states that this schema is written according to the draft v4 specification.
  • $id: This keyword defines a URI for the schema and the base URI that other URI references within the schema are resolved against.
  • title: This keyword is descriptive only as it does not add constraints to the data being validated. The intent of the schema is stated with the keyword title.
  • description: This keyword is used alongside the keyword title for description.
  • type: This keyword defines the first constraint on our JSON data. For this file, it must be a JSON Object.
  • properties: This keyword defines various keys and their value types.
  • required: This keyword keeps a list of required properties.
For a full list of keywords, you can check out json-schema.org. There you shall find all the keywords that you can use in your schema and find out its purpose.
There are various free online resources for you to build a JSON schema. If you want to build one on your own, you can start with the basics.
  • $schema: For standard and version control
  • $id: for URI for the schema, and the base URI that other URI references within the schema are resolved against.
  • title: to state the intent of the schema
  • description: give a description of the schema
  • type: to put a constraint on our JSON data. For this file, it must be a JSON Object.
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://example.com/employee.schema.json",
  "title": "Record of employee",
  "description": "This document records the details of an employee",
  "type": "object"
}
Moving forward, we add more properties to our JSON schema.
{
    "$schema": "http://json-schema.org/draft-04/schema#",
    "$id": "https://example.com/employee.schema.json",
    "title": "Record of employee",
    "description": "This document records the details of an employee",
    "type": "object",
    "properties": {
        "id": {
            "description": "A unique identifier for an employee",
            "type": "string"
        }
    }
}
Now, we use the keywords required, minimum to add constraints to our schema.
{
    "$schema": "http://json-schema.org/draft-04/schema#",
    "$id": "https://example.com/employee.schema.json",
    "title": "Record of employee",
    "description": "This document records the details of an employee",
    "type": "object",
    "properties": {
        "id": {
            "description": "A unique identifier for an employee",
            "type": "string"
        },
        "fullName": {
            "description": "full name of a person",
            "type": "string"
        },
        "age": {
            "description": "age of a person",
            "type": "number",
            "minimum": 16
        }
    },
    "required": [
        "id"  
        "fullName",
        "age"
    ]
}
As you can see, we are slowly building our schema by adding various properties. Properties are used to validate the JSON documents that we create. You can add more properties like boolean, enum to add more constraints based on the data type you require.
Now, for nested data, we can add properties within the data structure. Here, observe the hobbies array.
{
    "$schema": "http://json-schema.org/draft-04/schema#",
    "$id": "https://example.com/employee.schema.json",
    "title": "Record of employee",
    "description": "This document records the details of an employee",
    "type": "object",
    "properties": {
        "id": {
            "description": "A unique identifier for an employee",
            "type": "string"
        },
        "fullName": {
            "description": "fullname of a person",
            "type": "string"
        },
        "age": {
            "description": "age of a person",
            "type": "number",
            "minimum": 16
        },
        "position": {
            "description": "position of a person",
            "type": "string"
        },
        "company": {
            "description": "the name of the company where the person works",
            "type": "string"
        },
        "hobbies": {
            "description": "hobbies of the person",
            "type": "object",
            "properties": {
                "indoor": {
                    "type": "array",
                    "items": {
                        "description": "Enter your hobby",
                        "type": "string"
                    },
                    "minItems": 1,
                    "uniqueItems": true
                },
                "outdoor": {
                    "type": "array",
                    "items": {
                        "description": "Enter your hobby",
                        "type": "string"
                    },
                    "minItems": 1,
                    "uniqueItems": true
                }
            },
            "required": [
                "indoor",
                "outdoor"
            ]
        }
    },
    "required": [
        "id",
        "fullName",
        "age",
        "position",
        "company",
        "hobbies"
    ],
 "additionalProperties": false
}
As you can see, we have added constraints for hobbies within the nested data structure.
Lastly, we added additionalProperties: false as we don’t want additional information to be added to the JSON file.
When using JSON to send and receive files for your application, it’s best to use a NoSQL database like MongoDB Atlas. You can use MongoDB Atlas to create a free cluster where you can set up the database for your application. MongoDB stores the data in BSON (Binary JSON). So, you can store all your data in MongoDB in JSON format. After that, you can get started with using your JSON schema to validate the JSON files stored in the database. You can easily set validation rules by following the documentation of Set validation rules for your schema. You can use the $jsonSchema operator to match documents that satisfy the specified JSON Schema.The MongoDB JSON schema documentation is a good resource to understand how to use this operator. Diving into this topic would digress from the main article. If you want to learn more, you can find more information at JSON schema validation.
Data
{
  "name":"John",
  "age":30,
  "cars": [
    { "name":"Ford", "models":[ "Fiesta", "Focus", "Mustang" ] },
    { "name":"BMW", "models":[ "320", "X3", "X5" ] },
    { "name":"Fiat", "models":[ "500", "Panda" ] }
  ]
 }
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "name": {
      "type": "string"
    },
    "age": {
      "type": "integer"
    },
    "cars": {
      "type": "array",
      "items": [
        {
          "type": "object",
          "properties": {
            "name": {
              "type": "string"
            },
            "models": {
              "type": "array",
              "items": [
                {
                  "type": "string"
                },
                {
                  "type": "string"
                },
                {
                  "type": "string"
                }
              ]
            }
          },
          "required": [
            "name",
            "models"
          ]
        },
        {
          "type": "object",
          "properties": {
            "name": {
              "type": "string"
            },
            "models": {
              "type": "array",
              "items": [
                {
                  "type": "string"
                },
                {
                  "type": "string"
                },
                {
                  "type": "string"
                }
              ]
            }
          },
          "required": [
            "name",
            "models"
          ]
        },
        {
          "type": "object",
          "properties": {
            "name": {
              "type": "string"
            },
            "models": {
              "type": "array",
              "items": [
                {
                  "type": "string"
                },
                {
                  "type": "string"
                }
              ]
            }
          },
          "required": [
            "name",
            "models"
          ]
        }
      ]
    }
  },
  "required": [
    "name",
    "age",
    "cars"
  ]
}
Data
{
  "latitude": 58.858093,
  "longitude": 22.294694
}
Schema
{
  "$id": "https://example.com/geographical-location.schema.json",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "title": "Longitude and Latitude Values",
  "description": "A geographical coordinate.",
  "required": [ "latitude", "longitude" ],
  "type": "object",
  "properties": {
    "latitude": {
      "type": "number",
      "minimum": -90,
      "maximum": 90
    },
    "longitude": {
      "type": "number",
      "minimum": -180,
      "maximum": 180
    }
  }
}