JSON Schema Basics
Introduction
JSON has like XSL for XML a schema to validate de content of a JSON-file.
Schema files are name regularly named *.schema.json.
The json-schema.org
site has the detailed information.
Actually validation is needed while:
- Developing using an IDE (JetBrains/CLion)
- Command line unit testing (Python)
- In the code at runtime (C++)
For each a solution given including installation or configuration instructions.
Validation Example
This example uses references to other schema files for types or objects.
For the example the files are structured accordingly.
The File to Validate
Simple json-file named test.customer.json of customer to ship products.
Name of the file is important for the IDE (JetBrains) file mappings.
{
"name": {
"first": "Prins",
"middle": "van",
"last": "Oranje"
},
"billing_address": {
"street_address": "Noordeinde 68",
"postal_code": "2514GL",
"city": "'s-Gravenhage",
"state": "Zuid-Holland"
},
"shipping_address": {
"street_address": "Molenstraat 27",
"postal_code": "2513BJ",
"city": "'s-Gravenhage",
"state": "Zuid-Hoilland"
},
"parcel_size": {
"height": 200,
"width": 80,
"depth": 30
}
}
Schema Files for Validation
Multiple schema files are used to demonstrate a way to organize and reuse schemas in a structured way.
Definitions Schema
This file contains specific individual types and are referenced by multiple schema files.
It is also subject to a schema itself and in this case http://json-schema.org/draft-07/schema#.
{
"$id": "defs",
"$schema": "http://json-schema.org/draft-07/schema#",
"definitions": {
"firstName": {
"type": "string",
"minLength": 1,
"maxLength": 20
},
"middleName": {
"type": "string",
"minLength": 0,
"maxLength": 15
},
"lastName": {
"type": "string",
"minLength": 1,
"maxLength": 30
},
"cityName": {
"type": "string",
"pattern": "^.{1,40}$"
},
"stateName": {
"type": "string",
"pattern": "^.{1,40}$"
},
"parcelSizeHeight": {
"type": "number",
"maximum": 210,
"minimum": 30
},
"parcelSizeWidth": {
"type": "number",
"maximum": 85,
"minimum": 30
},
"parcelSizeDepth": {
"type": "number",
"maximum": 250,
"minimum": 30
},
"postalCode": {
"type": "string",
"pattern": "^[1-9][0-9]{3}[A-Z]{2}$"
}
}
}
Address Schema
This file describes an object and is referenced in full.
The file also references defs.schema.json for individual types.
{
"$id": "address",
"type": "object",
"additionalProperties": false,
"properties": {
"street_address": {
"type": "string"
},
"postal_code": {
"$ref": "defs.schema.json#/definitions/postalCode"
},
"city": {
"$ref": "defs.schema.json#/definitions/cityName"
},
"state": {
"$ref": "defs.schema.json#/definitions/stateName"
}
},
"required": [
"street_address",
"postal_code",
"city",
"state"
]
}
Customer Schema
This file uses a mix of objects like name which is locally defined.
Objects bgilling_address and shipping_address are externally defined.
In order for the validator (python3-jsonschema) to find the referenced schemas locally a full path file-url is needed.
{
"$id": "file://<full-dir-from-root>/schema/customer.schema.json",
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"additionalProperties": false,
"properties": {
"name": {
"type": "object",
"additionalProperties": false,
"properties": {
"first": {
"$ref": "defs.schema.json#/definitions/firstName"
},
"middle": {
"$ref": "defs.schema.json#/definitions/middleName"
},
"last": {
"$ref": "defs.schema.json#/definitions/lastName"
}
},
"required": [
"first",
"middle",
"last"
]
},
"shipping_address": {
"$ref": "address.schema.json"
},
"billing_address": {
"$ref": "address.schema.json"
},
"parcel_size": {
"type": "object",
"additionalProperties": false,
"properties": {
"height": {
"$ref": "defs.schema.json#/definitions/parcelSizeHeight"
},
"width": {
"$ref": "defs.schema.json#/definitions/parcelSizeWidth"
},
"depth": {
"$ref": "defs.schema.json#/definitions/parcelSizeDepth"
}
}
}
},
"required": [
"name",
"shipping_address",
"billing_address",
"parcel_size"
]
}
Actual Validation Options
Command-line
Python has an application which can be installed by installing package python3-jsonschema.
For debian with the apt package manager this is.
When done the command jsonschema is available and jsonschema --help tells that for our purpose
IDE (JetBrain/CLion)
In JetBrains products json-schemas can be configured using file mappings allowing wildcards.
Since the schema is also a JSON-file it is also subject to a schema itself and this is configured too.
In the JetBrains product like CLion go to "Settings | Languages & Frameworks | Schemas & DTDs | JSON Schema Mappings".
Add an external schema called "JSON Schema version 7" using URL http://json-schema.org/draft-07/schema and add file pattern *.schema.json.
Add another one called "Customer Data" using file <project-root>/schema/customer.schema.json and file pattern *.customer.json.
After this the file `test.customer.json in the editor is automatically validate. In the editor itself and in "Problems" tab the validation errors are reported.
Runtime in C++ Code
At the time of writing a working version is at GitHub pboettch/json-schema-validator
Add the file cmake/nlohmann_jsonConfig.cmake in the project with the following content.
# FetchContent added in CMake 3.11, downloads during the configure step.
include(FetchContent)
# Import Json library.
FetchContent_Declare(
json
GIT_REPOSITORY https://github.com/nlohmann/json
GIT_TAG v3.8.0
)
# Adds nlohmann_json::nlohmann_json
FetchContent_MakeAvailable(json)
Insert the following into the main CMakeLists.txt file to make it find the cmake/nlohmann_jsonConfig.cmake file.
# Make it so our own packages are found.
list(APPEND CMAKE_PREFIX_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake")
As of writing the GitHub nlohmann_json version is at v3.11.2.
It seems the library does not handle file URLs (file:///home/user/schema) but only HTTP of HTTPS protocols.