Schema Breakdown ~ Let's Build One
A schema is simply a JSON object with a set of properties appropriately named as desired object field names. Let's make a human schema.
var human = {
name: { },
birthday: { },
weight: { },
gender: { },
deceased: { }
};
Now we can define
type for each property.
var human = {
name: { type: 'string' },
birthday: { type: 'string' },
weight: { type: 'number' },
gender: { type: 'string' },
deceased: { type: 'boolean' }
};
At this stage the schema would validate an object with four, non-null appropriately named properties. Let's throw in some extra boundaries and rules...
var human = {
name: { type: 'string', min: 3, max: 120 },
birthday: { type: 'string', regex: /^(19|20)\d\d([- \/.])(0[1-9]|1[012])\2(0[1-9]|[12][0-9]|3[01])$/ },
weight: { type: 'number', null: true },
gender: { type: 'string', min: 1, max: 1 },
deceased: { type: 'boolean' }
};
- All properties are assumed to be required (not null) unless so specified (like the weight property).
- The regex property is used on string fields. The regex for birthday is simply a date regular expression in format yyyy-mm-dd.
- min and max can be used on string and number types.
Next: we can define label and custom.
- If a label property is defined and the object being validated fails, the validator will use the label property to describe the error.
- The custom property allows for a custom function to be defined in the schema. The function will be given two parameters; the property value, and the object being validated, in that order. The custom function should return an array of strings in the event of data not passing validation; and simply return nothing if validation was successful.
var human = {
name: { type: 'string', min: 3, max: 120, label: 'Full name' },
birthday: { type: 'string', regex: /^(19|20)\d\d([- \/.])(0[1-9]|1[012])\2(0[1-9]|[12][0-9]|3[01])$/ },
weight: { type: 'number', null: true },
gender: { type: 'string', min: 1, max: 1
custom: function(v) {
if (['F', 'M'].indexOf(v.toUpperCase()) == -1)
return ['Gender must be set to F or M.'];
}
},
deceased: { type: 'boolean' }
};
The last two features worth mention:
arrays and sub
schemas are both supported as well. Let's add some pets to our human.
var animal = {
name: { type: 'string', min: 3, max: 120 }
};
var human = {
name: { type: 'string', min: 3, max: 120, label: 'Full name' },
birthday: { type: 'string', regex: /^(19|20)\d\d([- \/.])(0[1-9]|1[012])\2(0[1-9]|[12][0-9]|3[01])$/ },
weight: { type: 'number', null: true },
gender: { type: 'string', min: 1, max: 1,
custom: function(v) {
if (['F', 'M'].indexOf(v.toUpperCase()) == -1)
return ['Gender must be set to F or M.'];
}
},
deceased: { type: 'boolean' },
pets: { type: 'object', schema: animal, array: true, null: true }
};
* Recursive behavior is not yet supported. (sad face)
The last code snippet above should validate positively on an object that looks like this:
{
name: 'Victor Challis',
birthday: '1982-12-14',
weight: null,
gender: 'M',
deceased: false,
pets: [
{ name: 'Alex' },
{ name: 'Pat' }
]
};
In case you didn't see it at the top, you can experiment with the validator on JSFiddle.net.