#Themis
Themis is a blazing fast, compiled JSON Schema v4 validator. Themis was created for use in environments where there is a large amount of data that has to be validated against the same schema multiple times. Eg: REST API Servers.
Themis (Greek: Θέμις) is an ancient Greek Titaness, the goddess of divine order, law, natural law and custom, and a prophetic goddess — the divine voice who first instructed mankind in the primal laws of justice and morality.
Themis was inspired by the z-schema and json-model validators and tries to provide the best of both worlds. Many thanks to Martin Zagora for his work on z-schema 3 from which most of the validation logic was adapted.
npm install themis
var Themis = require('themis');
var schema = {
"id": "basicSchema",
"type": "array",
"items": {
"title": "Product",
"type": "object",
"properties": {
"id": {
"description": "The unique identifier for a product",
"type": "number"
},
"name": {
"type": "string"
},
"price": {
"type": "number",
"minimum": 0,
"exclusiveMinimum": true
},
"tags": {
"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 with the product"
}
},
"required": ["id", "name", "price"]
}
}
var data = [
{
"id": 2,
"name": "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
}
},
{
"id": 3,
"name": "a blue mouse",
"price": 25.50,
"dimensions": {
"length": 3.1,
"width": 1.0,
"height": 1.0
},
"warehouselocation": {
"latitude": 54.4,
"longitude": -32.7
}
}
];
// Generate the validator
var validator = Themis.validator(schema);
// now validate our data against the schema
var report = validator(data, 'basicSchema');
console.log(require('util').inspect(report, { depth: 10, colors: true }));
// { valid: true, errors: [], subReport: [] }
At present themis does not support fetching remote json-schemas. You can however pre-fetch them and pass them in.
var Themis = require('themis');
var schemas = [
{
id: "personDetails",
type: "object",
properties: {
firstName: { type: "string" },
lastName: { type: "string" }
},
required: ["firstName", "lastName"]
},
{
id: "addressDetails",
type: "object",
properties: {
street: { type: "string" },
city: { type: "string" }
},
required: ["street", "city"]
},
{
id: "personWithAddress",
allOf: [
{ $ref: "personDetails" },
{ $ref: "addressDetails" }
]
}
];
var data = {
firstName: "Johny",
lastName: "Jose",
street: "24th Main, HSR Layout",
city: "Bangalore"
};
// Generate the validator
var validator = Themis.validator(schemas);
// now validate our data against the last schema
var report = validator(data, 'personWithAddress');
console.log(require('util').inspect(report, { depth: 10, colors: true }));
// { valid: true, errors: [] }
You can register custom format validators with Themis.
var Themis = require('../src/themis');
Themis.registerFormat('username', function (str) {
return /^[a-zA-Z0-9_\.-]+$/.test(str);
});
Themis.registerFormat('password', function (str) {
return /^(?=.{6,}).*$/.test(str);
});
Themis.registerFormat('identifier', function (str) {
return /^[a-zA-Z_][a-zA-Z0-9_]*$/.test(str);
});
var schema = {
"id": "player",
"type": "object",
"properties": {
"id": {
"type": "string",
"format": "identifier"
},
"username": {
"type": "string",
"format": "username"
},
"password" :{
"type": "string",
"format": "password"
}
}
};
var valid_player = {
"id": "frodo",
"username": "Frodo",
"password": "TheOneRing"
};
var invalid_player = {
"id": "123",
"username": "!@#",
"password": "foo"
};
// Generate the validator
var validator = Themis.validator(schema);
var report = validator(valid_player, 'player');
console.log(require('util').inspect(report, { depth: 10, colors: true }));
// { valid: true, errors: [] }
var report = validator(invalid_player, 'player');
console.log(require('util').inspect(report, { depth: 10, colors: true }));
/*
{ valid: false,
errors: [],
subReport:
[ { valid: false,
errors:
[ { code: 'INVALID_FORMAT',
schema: 'player/properties/id',
params: { actual: '123', expected: 'identifier' } } ] },
{ valid: false,
errors:
[ { code: 'INVALID_FORMAT',
schema: 'player/properties/username',
params: { actual: '!@#', expected: 'username' } } ] },
{ valid: false,
errors:
[ { code: 'INVALID_FORMAT',
schema: 'player/properties/password',
params: { actual: 'foo', expected: 'password' } } ] } ] }
*/
The Themis object contains methods to create validators and register formats.
Generate a new compiled validator from the provided schemas. The returned validator function can be reused any number of times. Check the examples above to see its usage.
Register a new format and its associated validation function.
Themis achieves its high performance by generating custom optimized validation functions for every json schema document provided to it. For most types of data Themis is atleast 5-10 times faster than Z-Schema 3 and atleast twice as fast as json-model.
Basic Object Validation
-----------------------
z-schema#basicObject x 15,421 ops/sec ±7.07% (56 runs sampled)
jayschema#basicObject x 205 ops/sec ±6.95% (59 runs sampled)
jjv#basicObject x 3,385 ops/sec ±5.43% (56 runs sampled)
jsonschema#basicObject x 388 ops/sec ±5.11% (59 runs sampled)
tv4#basicObject x 9,746 ops/sec ±2.81% (70 runs sampled)
json-model#basicObject x 29,009 ops/sec ±7.28% (69 runs sampled)
themis#basicObject x 96,757 ops/sec ±2.80% (55 runs sampled)
Fastest is themis#basicObject
Advanced Object Validation
--------------------------
z-schema#advancedObject x 2,704 ops/sec ±8.09% (60 runs sampled)
jayschema#advancedObject x 24.79 ops/sec ±5.88% (35 runs sampled)
jjv#advancedObject x 933 ops/sec ±6.32% (57 runs sampled)
jsonschema#advancedObject x 90.19 ops/sec ±6.21% (53 runs sampled)
tv4#advancedObject x 148 ops/sec ±8.47% (64 runs sampled)
json-model#advancedObject x 3,730 ops/sec ±2.04% (65 runs sampled)
themis#advancedObject x 10,173 ops/sec ±3.04% (65 runs sampled)
Fastest is themis#advancedObject
For a more detailed analysis of performance check out the benchmarks against the other popular json schema validators available today.
##TODO
- Support remote reference fetching.
- Validate json schemas before attempting validation.
- Add more benchmarks for different types of datasets.
- Better validation errors.
- Add support for browsers
Johny Jose <[email protected]>