JSON Model is a compact and intuitive JSON syntax to describe JSON data structures.
This reference implementation allows to generate code in Python, C, JavaScript, PL/pgSQL, Perl and Java for checking a JSON value against a JSON model, and to export models to JSON Schema or Pydantic.
It is dedicated to the Public Domain.
JSON Model optimizing compiler (jmc) can be installed as a
Python package or a
Docker image, see
Installation HOWTO.
Command jmc options include:
- main operations (default depends on other options, final guess is preprocess):
-P: preprocess model.-C: compile to Python, C, JS, PL/pgSQL, Perl, Java.-E: export to JSON Schema version draft 2020-12 or Pydantic.
-O: optimize model: constant propagation, partial evaluation, xor to or conversion, flattening… (this is the default,-nOto disable)-o output: file output instead of standard- …
For instance, let's consider a JSON model in file person.model.json:
{
"#": "A person with a birth date",
"name": "/^[a-z]+$/i",
"born": "$DATE"
}-
to check directly sample JSON values against it (with the Python backend):
jmc -r person.model.json hobbes.json oops.json
hobbes.json: PASS oops.json: FAIL (.: not an expected object [.]; .: missing mandatory prop <born> [.]) -
to compile an executable for checking a model (with the C backend), and use it for validating values:
jmc -o ./person.out person.model.json ./person.out -r hobbes.json oops.json
hobbes.json: PASS oops.json: FAIL (.: not an expected object [.]; .: missing mandatory prop <born> [.])The generated executable allow to collect validation performance figures (average and standard deviation) over a loop, with or without reporting:
./person.out -r -T 100000 hobbes.json
hobbes.json.[0] nop PASS 0.056 ± 0.423 µs/check (0.174) hobbes.json.[0] rep PASS 0.071 ± 0.443 µs/check (0.174) hobbes.json: PASS -
to export this model as a JSON schema in the YaML format:
jmc -E -F yaml person.model.json
description: A person with a birth date type: object properties: name: type: string pattern: (?i)^[a-z]+$ born: type: string format: date required: - name - born additionalProperties: false
The package provides functions to create and check models from Python:
import json_model as jm
# direct model definition with 2 mandatory properties
person_model: jm.Jsonable = {
"name": "/^[a-z]+$/i",
"born": "$DATE"
}
# create a dynamically compiled checker function for the model
checker = jm.model_checker_from_json(person_model)
# check valid data
good_person = { "name": "Hobbes", "born": "2020-07-29" }
print(good_person, "->", checker(good_person))
# check invalid data
bad_person = { "name": "Oops" }
print(bad_person, "->", checker(bad_person))
# collect reasons
reasons: jm.Report = []
assert not checker(bad_person, "", reasons)
print("reasons:", reasons)See the benchmark page for artifacts which compare various JSON Model Compiler runs (C, JS, Java, Python) with Sourcemeta Blaze CLI as a baseline using test cases from JSON Schema Benchmark. Overall, JMC-C implementation fares over 50% faster than Blaze C++. It comes ahead 80% of the time on the latest benchmarks tests. Moreover, JMC-JS and JMC-Java/GSON native implementations are only 25-30% slower than Blaze C++, which given the intrinsic language capabilities is quite honorable.
See the JSON Model website, which among many resources, includes a tutorial for a hands-on overview of JSON Model, and links to research papers for explanations about the design.