Improve your programming skills

JSON Schema essentials

Quick Q-A (source – Goog directly)

What is a JSON Schema used for?

Primarily, JSON Schema is used to validate data. The sorts of data JSON Schema can validate is data encoded in JSON. JSON stands for JavaScript Object Notation and is a subset of Javascript. JSON is both human and machine-readable, making it a popular format choice for data interchange.

What is JSON Schema form?

JSON Schema is a declarative language that allows you to annotate and validate JSON documents.

How to create schema for JSON?

  1. Click File > New > Other. A window opens in which you can select a wizard.
  2. Expand General, select File, click Next. The Create New File window opens.
  3. Select a parent folder and enter a file name for your JSON schema file. Give the file an extension of . schema. …
  4. Click Finish.

Do JSON files have schema?

JSON has a schema. REST services have WADL. Also there are tools like wadl2java . Old question, but worth clarifying: The JSON Schema standard includes “hyper-schemas”, which specify links/actions – including HTTP method, required data (specified as JSON Schema), and expected results

What is schema in REST API?

A schema is metadata that tells us how our data is structured. Most databases implement some form of schema which enables us to reason about our data in a more structured manner. The WordPress REST API utilizes JSON Schema to handle the structuring of its data.

Tutorial 1: JSON Schema

source: http://json-schema.org/learn/

Getting Started Step-By-Step

source: http://json-schema.org/learn/getting-started-step-by-step.html

Introduction

Let’s pretend we’re interacting with a JSON based product catalog. This catalog has a product which has:

  • An identifier: productId
  • A product name: productName
  • A selling cost for the consumer: price
  • An optional set of tags: tags.

For example:

{
  "productId": 1,
  "productName": "A green door",
  "price": 12.50,
  "tags": [ "home", "green" ]
}

While generally straightforward, the example leaves some open questions. Here are just a few of them:

  • What is productId?
  • Is productName required?
  • Can the price be zero (0)?
  • Are all of the tags string values?

When you’re talking about a data format, you want to have metadata about what keys mean, including the valid inputs for those keys. JSON Schema is a proposed IETF standard how to answer those questions for data.

IETF – Internet Engineering Task Force

Starting the schema

To start a schema definition, let’s begin with a basic JSON schema. We start with four properties called keywords which are expressed as JSON keys.

Yes. the standard uses a JSON data document to describe data documents, most often that are also JSON data documents but could be in any number of other content types like text/xml.

  • The $schema keyword states that this schema is written according to a specific draft of the standard and used for a variety of reasons, primarily version control.
  • The $id keyword defines a URI for the schema, and the base URI that other URI references within the schema are resolved against.
  • The title and description annotation keywords are descriptive only. They do not add constraints to the data being validated. The intent of the schema is stated with these two keywords.
  • The type validation keyword defines the first constraint on our JSON data and in this case it has to be a JSON Object.
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://example.com/product.schema.json",
"title": "Product",
"description": "A product in the catalog",
"type": "object"
}

All vacabulary are on this link: https://json-schema.org/draft/2020-12/json-schema-core.html#section-8.1.1

We introduce the following pieces of terminology when we start the schema:

  • Schema Keyword: $schema and $id.
  • Schema Annotations: title and description.
  • Validation Keyword: type.

Defining the properties

productId is a numeric value that uniquely identifies a product. Since this is the canonical identifier for a product, it doesn’t make sense to have a product without one, so it is required.

In JSON Schema terms, we update our schema to add:

  • The properties validation keyword.
  • The productId key.description schema annotation and type validation keyword is noted – we covered both of these in the previous section.
  • The required validation keyword listing productId.
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://example.com/product.schema.json",
"title": "Product",
"description": "A product from Acme's catalog",
"type": "object",
"properties": {
"productId": {
"description": "The unique identifier for a product",
"type": "integer"
}
},
"required": [ "productId" ]
}
  • productName is a string value that describes a product. Since there isn’t much to a product without a name it also is required.
  • Since the required validation keyword is an array of strings we can note multiple keys as required; We now include productName.
  • There isn’t really any difference between productId and productName – we include both for completeness since computers typically pay attention to identifiers and humans typically pay attention to names.
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://example.com/product.schema.json",
  "title": "Product",
  "description": "A product from Acme's catalog",
  "type": "object",
  "properties": {
    "productId": {
      "description": "The unique identifier for a product",
      "type": "integer"
    },
    "productName": {
      "description": "Name of the product",
      "type": "string"
    }
  },
  "required": [ "productId", "productName" ]
}

Going deeper with properties

According to the store owner there are no free products. 😉

  • The price key is added with the usual description schema annotation and type validation keywords covered previously. It is also included in the array of keys defined by the required validation keyword.
  • We specify the value of price must be something other than zero using the exclusiveMinimum validation keyword.
    • If we wanted to include zero as a valid price we would have specified the minimum validation keyword.
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://example.com/product.schema.json",
  "title": "Product",
  "description": "A product from Acme's catalog",
  "type": "object",
  "properties": {
    "productId": {
      "description": "The unique identifier for a product",
      "type": "integer"
    },
    "productName": {
      "description": "Name of the product",
      "type": "string"
    },
    "price": {
      "description": "The price of the product",
      "type": "number",
      "exclusiveMinimum": 0
    }
  },
  "required": [ "productId", "productName", "price" ]
}

Next, we come to the tags key.

The store owner has said this:

  • If there are tags there must be at least one tag,
  • All tags must be unique; no duplication within a single product.
  • All tags must be text.
  • Tags are nice but they aren’t required to be present.

Therefore:

  • The tags key is added with the usual annotations and keywords.
  • This time the type validation keyword is array.
  • We introduce the items validation keyword so we can define what appears in the array. In this case: string values via the type validation keyword.
  • The minItems validation keyword is used to make sure there is at least one item in the array.
  • The uniqueItems validation keyword notes all of the items in the array must be unique relative to one another.
  • We did not add this key to the required validation keyword array because it is optional.
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://example.com/product.schema.json",
  "title": "Product",
  "description": "A product from Acme's catalog",
  "type": "object",
  "properties": {
    "productId": {
      "description": "The unique identifier for a product",
      "type": "integer"
    },
    "productName": {
      "description": "Name of the product",
      "type": "string"
    },
    "price": {
      "description": "The price of the product",
      "type": "number",
      "exclusiveMinimum": 0
    },
    "tags": {
      "description": "Tags for the product",
      "type": "array",
      "items": {
        "type": "string"
      },
      "minItems": 1,
      "uniqueItems": true
    }
  },
  "required": [ "productId", "productName", "price" ]
}

TK: as you see, in tags property, the data type is defined twince – for array and array values

Nesting data structures

Up until this point we’ve been dealing with a very flat schema – only one level. This section demonstrates nested data structures.

  • The dimensions key is added using the concepts we’ve previously discovered. Since the type validation keyword is object we can use the properties validation keyword to define a nested data structure.
    • We omitted the description annotation keyword for brevity in the example. While it’s usually preferable to annotate thoroughly in this case the structure and key names are fairly familiar to most developers.
  • You will note the scope of the required validation keyword is applicable to the dimensions key and not beyond.
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://example.com/product.schema.json",
  "title": "Product",
  "description": "A product from Acme's catalog",
  "type": "object",
  "properties": {
    "productId": {
      "description": "The unique identifier for a product",
      "type": "integer"
    },
    "productName": {
      "description": "Name of the product",
      "type": "string"
    },
    "price": {
      "description": "The price of the product",
      "type": "number",
      "exclusiveMinimum": 0
    },
    "tags": {
      "description": "Tags for the product",
      "type": "array",
      "items": {
        "type": "string"
      },
      "minItems": 1,
      "uniqueItems": true
    },
    "dimensions": {
      "type": "object",
      "properties": {
        "length": {
          "type": "number"
        },
        "width": {
          "type": "number"
        },
        "height": {
          "type": "number"
        }
      },
      "required": [ "length", "width", "height" ]
    }
  },
  "required": [ "productId", "productName", "price" ]
}

References outside the schema

So far our JSON schema has been wholly self contained. It is very common to share JSON schema across many data structures for reuse, readability and maintainability among other reasons.

For this example we introduce a new JSON Schema resource and for both properties therein:

  • We use the minimum validation keyword noted earlier.
  • We add the maximum validation keyword.
  • Combined, these give us a range to use in validation.
{
  "$id": "https://example.com/geographical-location.schema.json",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "title": "Longitude and Latitude",
  "description": "A geographical coordinate on a planet (most commonly Earth).",
  "required": [ "latitude", "longitude" ],
  "type": "object",
  "properties": {
    "latitude": {
      "type": "number",
      "minimum": -90,
      "maximum": 90
    },
    "longitude": {
      "type": "number",
      "minimum": -180,
      "maximum": 180
    }
  }
}

Next we add a reference to this new schema so it can be incorporated.

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://example.com/product.schema.json",
  "title": "Product",
  "description": "A product from Acme's catalog",
  "type": "object",
  "properties": {
    "productId": {
      "description": "The unique identifier for a product",
      "type": "integer"
    },
    "productName": {
      "description": "Name of the product",
      "type": "string"
    },
    "price": {
      "description": "The price of the product",
      "type": "number",
      "exclusiveMinimum": 0
    },
    "tags": {
      "description": "Tags for the product",
      "type": "array",
      "items": {
        "type": "string"
      },
      "minItems": 1,
      "uniqueItems": true
    },
    "dimensions": {
      "type": "object",
      "properties": {
        "length": {
          "type": "number"
        },
        "width": {
          "type": "number"
        },
        "height": {
          "type": "number"
        }
      },
      "required": [ "length", "width", "height" ]
    },
    "warehouseLocation": {
      "description": "Coordinates of the warehouse where the product is located.",
      "$ref": "https://example.com/geographical-location.schema.json"
    }
  },
  "required": [ "productId", "productName", "price" ]
}

Taking a look at data for our defined JSON Schema

We’ve certainly expanded on the concept of a product since our earliest sample data (scroll up to the top). Let’s take a look at data which matches the JSON Schema we have defined.

  {
    "productId": 1,
    "productName": "An ice sculpture",
    "price": 12.50,
    "tags": [ "cold", "ice" ],
    "dimensions": {
      "length": 7.0,
      "width": 12.0,
      "height": 9.5
    },
    "warehouseLocation": {
      "latitude": -78.75,
      "longitude": 20.4
    }
  }

TK TODO: How to validate JSON Schema?

Leave a comment

Your email address will not be published. Required fields are marked *