Search This Blog

Tuesday, April 19, 2016

JSON Schema

Today JSON files replaces slowly but surely XML files. JSON certainly is more compact and is easier to work with in JS as they are nothing else than JS objects (JS Object Notation).

However even if JSON files are convenient for many things, being smaller, being faster to write, they had a huge drawback in my opinion over XML. The lack of schema definition which would allow to test if a JSON file is valid or not and makes the IDE aware of what we could write within.

Yet some IDE starts to support JSON Schema definitions ( http://json-schema.org/ ) for example Visual Studio (which actually is the one which interest me).

That finally close the issue I have with JSON and let me enforce a bit more strength inside my JSON configuration files.

Let's start with a small JSON file:
{
  "stores": [
    {
      "name""My Little Book Shop",
      "owner""Me Myself",
      "location": {
        "address""Av. Somewhere 29",
        "city""Someplace",
        "postal_code""5000",
        "country""MyCountry"      }
    }
  ],
  "books": {
    "How To Code for Dummies": {
      "isbn""12389298732",
      "price": 53.12
    },
    "I love ponies": {
      "isbn""98727356128",
      "price": 23.99
    }
  }
}
This file contains book shops and a list of books we can find.

Now so far nothing special, however how to ensure that the content of this JSON file is correct and that the next time we type something in we don't make mistakes? Quick answer: by using a JSON Schema!

To do so in our JSON file we need to add a property (usually the first one): "$schema": "book.schema.json"

This tells the IDE that for this JSON file we will use the file book.schema.json as schema. Of course this file is now missing so let's create it:
{
  "$schema""http://json-schema.org/draft-04/schema",
  "properties": {
    "$schema": { },
    "stores": { },
    "books": { }
  },
  "additionalProperties"false}
This small schema file defines that the JSON file can contains ONLY 3 properties: $schema, stores and books. Everything else would be prohibited. That's already a first step, but let's define what in the stores can be placed as value:
{
  "$schema""http://json-schema.org/draft-04/schema",
  "properties": {
    "$schema": { "type""string" },
    "stores": {
      "type""array",
      "items": {
        "type""object",
        "properties": {
          "name": { "type""string" },
          "owner": { "type""string" },
          "location": {
            "type""object",
            "properties": {
              "address": { "type""string" },
              "city": { "type""string" },
              "postal_code": { "type""string" },
              "country": { "type""string" }
            },
            "additionalProperties"false          }
        },
        "additionalProperties"false      }
    },
    "books": { }
  },
  "additionalProperties"false}
The same can be done for the "books" property, yet this one is a key / value pair and therefore need to be defined as "additionalProperties" while defining the type stored:
{
  "$schema""http://json-schema.org/draft-04/schema",
  "properties": {
    "$schema": { "type""string" },
    "stores": {
      "type""array",
      "items": {
        "type""object",
        "properties": {
          "name": { "type""string" },
          "owner": { "type""string" },
          "location": {
            "type""object",
            "properties": {
              "address": { "type""string" },
              "city": { "type""string" },
              "postal_code": { "type""string" },
              "country": { "type""string" }
            },
            "additionalProperties"false          }
        },
        "additionalProperties"false      }
    },
    "books": {
      "type""object",
      "additionalProperties": {
        "type""object",
        "properties": {
          "isbn": { "type""string" },
          "price": { "type""number" }
        },
        "additionalProperties"false      }
    }
  },
  "additionalProperties"false}
The schema is now complete for our JSON file, you could then check if something is valid or not, and also the IDE should propose you what kind of properties a given object should have. To further improve the schema I would strongly suggest to provide a description of the properties as well and therefore further help you while entering data within the JSON file:
{
  "$schema""http://json-schema.org/draft-04/schema",
  "properties": {
    "$schema": { "type""string" },
    "stores": {
      "type""array",
      "description""Lists all the shop in the francise.",
      "items": {
        "type""object",
        "properties": {
          "name": {
            "type""string",
            "description""Name of the shop."          },
          "owner": {
            "type""string",
            "description""Name of the owner of the shop."          },
          "location": {
            "type""object",
            "description""Location of the shop.",
            "properties": {
              "address": {
                "type""string",
                "description""Address of the shop"              },
              "city": {
                "type""string",
                "description""City where the shop is."              },
              "postal_code": {
                "type""string",
                "description""Postal code."              },
              "country": {
                "type""string",
                "description""Country of the shop."              }
            },
            "additionalProperties"false          }
        },
        "additionalProperties"false      }
    },
    "books": {
      "type""object",
      "description""List of all the books the shops can sell.",
      "additionalProperties": {
        "type""object",
        "properties": {
          "isbn": {
            "type""string",
            "description""Unique ID linked to a book. The ISBN is usually printed on the book itself."          },
          "price": {
            "type""number",
            "description""Usual price the book will be sold at."          }
        },
        "additionalProperties"false      }
    }
  },
  "additionalProperties"false}
Finally you can test the schema and the JSON provided here on an online validator like:
http://www.jsonschemavalidator.net/

The validator will not show the description while you type but will ensure the properties are acceptable for example.

After all this work, if you have a good IDE, you should have a result like this while working on your JSON file:


No comments:

Post a Comment