JSON (JavaScript Object Notation) is a simple and lightweight text-based data format. JSON Schema is an IETF standard providing a format for what JSON data is required for a given application and how to interact with it. Applying such standards for a JSON document lets you enforce consistency and data validity across similar JSON data.
.Let's take a look at a document example with a person's name and their indoor and outdoor hobbies.
{
"id": 7,
"name": "John Doe",
"age": 22,
"hobbies": {
"indoor": [
"Chess"
],
"outdoor": [
"BasketballStand-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. Additionally, JSON Schema gives you a standard way to structure the metadata.
Let’s look at an example of a JSON Schema for the above document type.
{
"$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": "number"
},
"name": {
"description": "Full name of the employee",
"type": "string"
},
"age": {
"description": "Age of the employee",
"type": "number"
},
"hobbies": {
"description": "Hobbies of the employee",
"type": "object",
"properties": {
"indoor": {
"type": "array",
"items": {
"description": "List of indoor hobbies",
"type": "string"
}
},
"outdoor": {
"type": "array",
"items": {
"description": "List of outdoor hobbies",
"type": "string"
}
}
}
}
}
}
It could look daunting at first glance but we will 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.
For a full list of keywords, visit json-schema.org. The link explains the keywords that you can use in your schema and their purpose.
You can use online JSON schema generators if you have a simple JSON document, then modify the schema as per the requirement of your project. Alternatively, you can build a JSON schema of your own from scratch by following the steps below
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 an employee.
{
"$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:
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. Lets build on it 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": "number"
}
}
}
We have added two sub-properties, “id.description”, stating that it is a unique identifier, and “id.type”, explaining that it is a number.
Let's do the same for name and age -- but this time, with new 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"
"minLength":2
},
"age": {
"description": "age of the employee",
"type": "number",
"minimum": 16
}
},
"required": [
"id"
"name",
"age"
]
}
In the name property, we have introduced the minLength
keyword to make sure that the property has at least two characters. Similarly, in the age property, we have used the minimum
keyword to ensure that the age of the employee exceeds 16 everytime. It can be of type number or type integer. We have also used the required
keyword to define the mandatory properties. Now, 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. Creating subschemas for Nested objects work quite similarly to the creating schemas for root objects. You can use all the schema keywords that you used when defining the root object except for $schema
and $id
. They only have to be stated at the beginning of a schema.
The following example shows how we can create an object within an object that takes an array type data. Here, 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": "number"
},
"name": {
"description": "name of the employee",
"type": "string",
"minLength":2
},
"age": {
"description": "age of the employee",
"type": "number",
"minimum": 16
},
"hobbies": {
"description": "hobbies of the employee",
"type": "object",
"properties": {
"indoor": {
"type": "array",
"items": {
"description": "List of hobbies",
"type": "string"
},
"minItems": 1,
"uniqueItems": true
},
"outdoor": {
"type": "array",
"items": {
"description": "List of hobbies",
"type": "string"
},
"minItems": 1,
"uniqueItems": true
}
},
"required": [
"indoor",
"outdoor"
]
}
},
"required": [
"id",
"name",
"age",
"hobbies"
],
"additionalProperties": false
}
In the above example, we have defined two array fields - indoor and outdoor in the “hobbies” object. You might have noticed the items
keyword. This keyword defines the properties of each item.
Similarly, minItems
defines the minimum number of items that must be present in the array, maxItems
defines the maximum number of items that can be present within the array uniqueItems
uniquely identifies each item.
You will also see the required keyword again within the subobject. Like the required keyword in the root JSON object, the required keyword within the subobject dictates the mandatory properties within the subobjects.
Lastly, we have also introduced additionalProperties
. In the above example, it is a boolean taking the value false , telling us that we can’t use any other property that isn’t listed under the properties
keyword.
However, additionalProperties
doesn’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 is required to be of type string.
"additionalProperties": { "type": "string" }
Though the above example is limited to a use case, there are limitless uses 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.
You can use $jsonSchema in a document validator to enforce the specified schema on insert and update operations in MongoDB, including in MongoDB Atlas. Since MongoDB stores the data in BSON (Binary JSON), you can easily store and retrieve all your data in JSON format.
MongoDB also lets you enforce a schema to validate your data and maintain a data structure. We will use MongoDB Atlas and MongoDB Compass to demonstrate how.
Suppose we insert the following documents into a collection named employees inside a database named mongodatabase.
Document 1
{
"id": 7,
"name": "John Doe",
"age": 22,
"hobbies": {
"indoor": [
"Chess"
],
"outdoor": [
"Basketball"
]
}
}
Document 2
{
"id": 8,
"name": "Jonathon Smith",
"age": 22
}
Document 3
{
"id": 1,
"name": "Jane Doe",
"age": 25,
"hobbies": {
"indoor": [
"Chess"
],
"outdoor": [
"Football"
]
}
}
We will enforce the schema from the previous section to validate these documents in MongoDB Compass.
Firstly, let’s connect our cluster with our Compass.
mongodb+srv://<username>:<password>@cluster0.9ddm0.mongodb.net/test
Replace <username> and <password> with the username and password of the database user that you created.
Now, let’s go into the mongodatabase and look at the documents inside the employees collection.
Click on the Validation tab and insert the following JSON schema to validate our documents. Begin the schema definition with $jsonSchema
keyword. Because we don’t need the $id and $schema keywords to get started, we will remove them.
{
$jsonSchema: {
"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": "number"
},
"name": {
"description": "name of the employee",
"type": "string",
"minLength":2
},
"age": {
"description": "age of the employee",
"type": "number",
"minimum": 16
},
"hobbies": {
"description": "hobbies of the employee",
"type": "object",
"properties": {
"indoor": {
"type": "array",
"items": {
"description": "List of hobbies",
"type": "string"
},
"minItems": 1,
"uniqueItems": true
},
"outdoor": {
"type": "array",
"items": {
"description": "List of hobbies",
"type": "string"
},
"minItems": 1,
"uniqueItems": true
}
},
"required": [
"indoor",
"outdoor"
]
}
},
"required": [
"id",
"name",
"age",
"hobbies"
],
"additionalProperties": false
}
}
If you have followed the steps so far, you should get the following result.
As our schema requires a hobbies field in every document, the document with the id: 8 fails because it didn’t contain the required field.
You can also set additional validation rules by following the documentation on setting validation rules for your schema. To match documents that satisfy the specified JSON Schema, you can use the $jsonSchema
operator. The MongoDB JSON Schema documentation is an excellent resource to get you up and running.
To learn more about MongoDB Atlas, refer to this article.
By now, you should understand 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 learn more about JSON Schema with MongoDB, we recommend you go through MongoDB’s JSON Schema validation resource. If you are interested in knowing more about JSON Schema validation generally, visit this article.
Yes. JSON Schema is considered to be a standard way to enforce JSON structure validity.
Explore more articles: