What is a JSON Schema? Find here: https://json-schema.org/
- v6 - old version which has been around a long time, supports JSON Schema draft-04
- v7 - modernized version (to ESM module with Typescript) which passes all tests from JSON Schema Test Suite for draft-04
- v8 - by default assumes all schemas without $schema tag are draft-04, the old behaviour from v7 can be explicitly turned on by specifying
validator = ZSchema.create({ version: 'none' }); - v9 - new api,
new ZSchema()replaced byZSchema.create()for initialization
Validator will try to perform sync validation when possible for speed, but supports async callbacks when they are necessary.
import ZSchema from 'z-schema';
const validator = ZSchema.create();const ZSchema = require('z-schema');
const validator = ZSchema.create();<script type="text/javascript" src="z-schema/umd/ZSchema.min.js"></script>
<script type="text/javascript">
var validator = ZSchema.create();
try {
validator.validate('string', { type: 'string' });
console.log('Validation passed');
} catch (error) {
console.log('Validation failed:', error.details);
}
</script>npm install --global z-schema
z-schema --help
z-schema mySchema.json
z-schema mySchema.json myJson.json
z-schema --strictMode mySchema.json myJson.jsonYou can pre-validate and compile schemas using the validateSchema method. This is useful for server startup to ensure all schemas are valid and to resolve $ref references between schemas.
const 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' }],
},
];
try {
validator.validateSchema(schemas);
console.log('All schemas are valid and compiled');
} catch (error) {
console.log('Schema validation failed:', error.details);
}The validate method automatically compiles and validates the schema before validating the JSON data against it. For better performance, you can pre-compile schemas using validateSchema during initialization.
try {
validator.validate(json, schema);
// validation passed
} catch (error) {
// this will return a native error object with name and message
console.log(error.name); // 'z-schema validation error'
console.log(error.message); // common error message
// this will return an array of validation errors encountered
console.log(error.details); // array of detailed errors
}
// Or use validateSafe for object-based result
const result = validator.validateSafe(json, schema);
if (!result.valid) {
console.log(result.errs); // array of error objects
}
...ZSchema supports custom format validators that can perform both synchronous and asynchronous validation. This example shows how to validate a person payload with:
- Async validation: User ID against a database
- Async validation: Postcode against an external service
- Sync validation: Phone number format
import ZSchema from 'z-schema';
import db from './db';
// Initialize ZSchema
const validator = ZSchema.create();
// Register async and sync format validators
validator.registerFormat('user-exists', async (input: unknown): Promise<boolean> => {
if (typeof input !== 'number') return false;
const user = await db.getUserById(input);
return user != null;
});
validator.registerFormat('valid-postcode', async (input: unknown): Promise<boolean> => {
if (typeof input !== 'string') return false;
const postcode = await db.getPostcode(input);
return postcode != null;
});
validator.registerFormat('phone-number', (input: unknown): boolean => {
if (typeof input !== 'string') return false;
const phoneRegex = /^\+?[1-9]\d{1,14}$/;
return phoneRegex.test(input);
});
// Define the JSON Schema
const personSchema = {
$schema: 'http://json-schema.org/draft-04/schema#',
type: 'object',
required: ['personId', 'address'],
properties: {
personId: {
type: 'number',
format: 'user-exists',
},
address: {
type: 'object',
required: ['postcode', 'phone'],
properties: {
postcode: {
type: 'string',
format: 'valid-postcode',
},
phone: {
type: 'string',
format: 'phone-number',
},
},
},
},
};
// Example payload
const payload = {
personId: 'user123',
address: {
postcode: 'SW1A 1AA',
phone: '+441234567890',
},
};
// Validate asynchronously
try {
const validator = ZSchema.create({ async: true });
await validator.validate(payload, personSchema);
console.log('✅ Validation successful!');
} catch (err) {
console.log('❌ Validation failed:', err);
}
// or validate without try-catch
const validator = ZSchema.create({ async: true, safe: true });
const res = await validator.validate(payload, personSchema);
if (res.valid) {
console.log('✅ Validation successful!');
} else {
console.log('❌ Validation failed:', res.err);
}In case you have some remote references in your schemas, you have to download those schemas before using validator.
Otherwise you'll get UNRESOLVABLE_REFERENCE error when trying to compile a schema.
var validator = ZSchema.create();
var json = {};
var schema = { "$ref": "http://json-schema.org/draft-04/schema#" };
try {
validator.validate(json, schema);
// This won't reach here due to unresolvable reference
} catch (error) {
// error.details will contain the validation errors
console.log(error.details[0].code); // "UNRESOLVABLE_REFERENCE"
}
var requiredUrl = "http://json-schema.org/draft-04/schema";
request(requiredUrl, function (error, response, body) {
validator.setRemoteReference(requiredUrl, JSON.parse(body));
try {
validator.validate(json, schema);
// validation passed
} catch (error) {
// shouldn't happen after setting remote reference
}
}If you're able to load schemas synchronously, you can use ZSchema.setSchemaReader feature:
ZSchema.setSchemaReader(function (uri) {
var someFilename = path.resolve(__dirname, '..', 'schemas', uri + '.json');
return JSON.parse(fs.readFileSync(someFilename, 'utf8'));
});See FEATURES.md for a full list of features.
See OPTIONS.md for all available options and their descriptions.
These repository has several submodules and should be cloned as follows:
git clone --recursive https://github.com/zaggino/z-schema.git
Big thanks to:
and to everyone submitting issues on GitHub