- Basics
- Advanced
- Misc
JSON-Schema-faker (or jsf
for short) combines two things:
- The JSON-schema specification, that defines what is the allowed content of a JSON document
- Fake data generators, that are used to generate basic or complex data, conforming to the schema.
Since
v0.5.x
external generators are not longer bundled withjsf
, however built-in defaults are shipped for all basic types and formats.
import jsf from 'json-schema-faker';
const schema = {
type: 'object',
properties: {
user: {
type: 'object',
properties: {
id: {
$ref: '#/definitions/positiveInt'
},
name: {
type: 'string',
faker: 'name.findName'
},
email: {
type: 'string',
format: 'email',
faker: 'internet.email'
}
},
required: ['id', 'name', 'email']
}
},
required: ['user'],
definitions: {
positiveInt: {
type: 'integer',
minimum: 0,
exclusiveMinimum: true
}
}
};
// use the async-version (preferred way)
jsf.resolve(schema).then(sample => {
console.log(sample);
// "[object Object]"
console.log(sample.user.name);
// "John Doe"
});
// sync-version (blocking)
jsf.generate(schema); // [object Object]
- json-schema.org/example1.html: warehouse location, Product from Acme catalog
- json-schema.org/example2.html: diskDevice storage type, diskUUID storage type, nfs storage type, tmpfs storage type
Notice these tools can be outdated, please open a PR for helping them or raise and issue in their respective repositories.
Use angular-jsf
module (installable via npm
and bower
) to get jsf
working in your angular app out of the box! And check out angular-jsf demo.
Use grunt-jsonschema-faker
to automate running json-schema-faker
against your JSON schemas.
Use json-schema-faker-cli
to run jsf
from your command line.
Use json-schema-faker-loader
to execute jsf
as a webpack loader.
Currently jsf
supports the JSON-Schema specification draft-04 only.
If you want to use draft-03, you may find useful information here.
There are plans to support latest
draft-06
anddraft-07
but currently is out of scope until a stable0.5.x
API is released.
Below is the list of supported keywords:
$ref
— Resolve internal references only, and/or external if provided.required
— All required properties are guaranteed, if not can be omitted.pattern
— Generate samples based on RegExp values.format
— Core formats v4-draft only:date-time
,email
,hostname
,ipv4
,ipv6
anduri
— alsouri-reference
,uri-template
,json-pointer
anduuid
are supported. -- demo »enum
— Returns any of these enumerated values.minLength
,maxLength
— Applies length constraints to string values.minimum
,maximum
— Applies constraints to numeric values.exclusiveMinimum
,exclusiveMaximum
— Adds exclusivity for numeric values.multipleOf
— Multiply constraints for numeric values.items
— Support for subschema and fixed item values.minItems
,maxItems
— Adds length constraints for array items.uniqueItems
— Applies uniqueness constraints for array items.additionalItems
— Partially supported (?)allOf
,oneOf
,anyOf
— Subschema combinators.properties
— Object properties to be generated.minProperties
,maxProperties
— Adds length constraints for object properties.patternProperties
— RegExp-based object properties.additionalProperties
— Partially supported (?)dependencies
— Partially supported (?)not
— Not supported yet (?)
Notice
not
support is complex to achieve and is probably will not work as you expected, most opened issues are related to that: so any feedback there is very appreaciated!
Inline references are fully supported (json-pointers) but external can't be resolved by jsf
.
Remote en local references are automatically resolved thanks to json-schema-ref-parser
.
const schema = {
type: 'object',
properties: {
someValue: {
$ref: 'otherSchema'
}
}
};
const refs = [
{
id: 'otherSchema',
type: 'string'
}
];
jsf.resolve(schema, refs).then(sample => {
console.log(sample.someValue);
// "voluptatem"
});
Local references are always resolved from the
process.cwd()
, of course you can specify a custom folder to look-up:jsf.resolve(schema, refs, cwd)
jsf
has built-in generators for core-formats, Faker.js and Chance.js (and others) are also supported but they require setup:
jsf.extend('faker', () => require('faker'));
{
"type": "string",
"faker": "internet.email"
}
(demo »)
The above schema will invoke faker.internet.email()
.
Note that both generators has higher precedence than format.
You can also use standard JSON Schema keywords, e.g. pattern
:
{
"type": "string",
"pattern": "yes|no|maybe|i don't know"
}
(demo »)
In following inline code examples the faker
and chance
variables are assumed to be created with, respectively:
import faker from 'faker';
import Chance from 'chance';
jsf.extend('faker', () => faker);
jsf.extend('chance', () => new Chance());
E.g. using chance
to faking values while passing arguments to the generator:
{
"type": "string",
"chance": {
"email": {
"domain": "fake.com"
}
}
}
(demo »)
...which will invoke chance.email({ "domain": "fake.com" })
.
This example works for single-parameter generator function.
However, if you pass multiple arguments to the generator function, just pass them wrapped in an array.
In the example below we use the faker.finance.amount(min, max, dec, symbol)
generator which has 4 parameters. We just wrap them with an array and it's equivalent to faker.finance.amount(100, 10000, 2, "$")
:
{
"type": "object",
"properties": {
"cash": {
"type": "string",
"faker": {
"finance.amount": [100, 10000, 2, "$"]
}
}
},
"required": [
"cash"
]
}
(demo »)
However, if you want to pass a single parameter that is an array itself, e.g.
chance.pickone(["banana", "apple", "orange"])
,
just like described here,
then you need to wrap it with an array once more (twice in total). The outer brackets determine that the content is gonna be a list of params injected into the generator. The inner brackets are just the value itself - the array we pass:
{
"type": "object",
"properties": {
"food": {
"type": "string",
"chance": {
"pickone": [
[
"banana",
"apple",
"orange"
]
]
}
}
},
"required": [
"food"
]
}
(demo »)
Additionally, you can add custom generators for those:
jsf.format('semver', () => jsf.random.randexp('\\d\\.\\d\\.[1-9]\\d?'));
Now that format can be generated:
{
"type": "string",
"format": "semver"
}
Usage:
- format() — Return all registered formats (custom only)
- format(obj) — Register formats by key/value → name/callback
- format(name) — Returns that format generator (undefined if not exists)
- format(name, callback) — Register a custom format by name/callback
If you provide
null
as callback the format will be unregistered, the same if you passnull
as the name: all added formats will be unregistered too.
Callback:
- schema (object) — The schema for input
Note that custom generators has lower precedence than core ones.
You may define following options for jsf
that alter its behavior:
jsf.option({
failOnInvalidTypes: false
});
// also valid
jsf.option('alwaysFakeOptionals', true);
Please read the available options here.
You may extend Faker.js:
import jsf from 'json-schema-faker';
jsf.extend('faker', () => {
const faker = require('faker');
faker.locale = 'de'; // or any other language
faker.custom = {
statement: length => {
return faker.name.firstName() + " has " + faker.finance.amount() + " on " + faker.finance.account(length) + ".";
}
};
return faker;
});
const schema = {
"type": "string",
"faker": {
"custom.statement": [19]
}
}
jsf.resolve(schema).then(...);
...or if you want to use faker's individual localization packages, simply do the following:
jsf.extend('faker', () => {
// just ignore the passed faker instance
const faker = require('faker/locale/de');
// do other stuff
return faker;
});
You can also extend Chance.js, using built-in chance.mixin function:
import jsf from 'json-schema-faker';
jsf.extend('chance', () => {
const Chance = require('chance');
const chance = new Chance();
chance.mixin({
'user': function() {
return {
first: chance.first(),
last: chance.last(),
email: chance.email()
};
}
});
return chance;
});
const schema = {
"type": "string",
"chance": "user"
}
jsf.resolve(schema).then(...);
The first parameter of extend
function is the generator name (faker
, chance
, etc.). The second one is the function that must return the dependency library.
JSON Schema does not require you to provide the type
property for your JSON Schema documents and document fragments.
But since jsf
uses the type
property to create the proper fake data, we attempt to infer the type whenever it is not provided. We do this based on the JSON Schema validation properties you use.
Now this means that if you do not use any of the JSON Schema validation properties, jsf will not be able to infer the type for you and you will need to explicitly set your
type
manually.)
Below is the list of JSON Schema validation properties and the inferred type based on the property:
- array —
additionalItems
,items
,maxItems
,minItems
anduniqueItems
- integer —
exclusiveMaximum
,exclusiveMinimum
,maximum
,minimum
andmultipleOf
- number — same as above
- object —
additionalProperties
,dependencies
,maxProperties
,minProperties
,patternProperties
,properties
andrequired
- string —
maxLength
,minLength
,pattern
andformat
- JSON, JSON Schema & JSON-schema-faker - WarsawJS meetup presentation recording, a step-by-step guide to JSON-related tools, including
jsf
There were some existing projects or services trying to achieve similar goals as jsf
:
- http://www.json-generator.com/
- https://github.com/unindented/fake-json
- https://github.com/jonahkagan/schematic-ipsum
- https://www.npmjs.org/package/json-schema-mock
- https://github.com/thaume/json-schema-processor
- https://github.com/andreineculau/json-schema-random
- https://github.com/murgatroid99/json-schema-random-instance
- https://github.com/tomarad/JSON-Schema-Instantiator
...but they were either incomplete, outdated, broken or non-standard. That's why jsf
was created.