Skip to main content

Validation with JSON Schema

All fab4m forms can generate a JSON Schema from their definition. This is very useful when you want to validate your form data on the server side.

Generating a JSON Schema

Consider the following form:

const form = createForm({
username: textField({ required: true, validators: [minLength(5)] }),
age: integerField({ label: "Username" }),
city: textField({
required: true,
validators: [allowedValues(["Gothenburg", "Stockholm"])],
}),
vegetarian: booleanField({ label: "Vegetarian" }),
interests: textField({ label: "Interests", multiple: true, minItems: 2 }),
profession: group(
{ label: "Profession" },
{
workplace: textField({ label: "Workplace" }),
label: textField({ label: "Label" }),
}
),
});

This data behind this form is quite complex to validate manually, luckily we don't have to, we can generate a schema for it and use that schema for validation instead.

Fab4m provides the generateSchemafunction to generate a schema for any form:

import { generateSchema } from "@fab4m/fab4m";
generateSchema(form);

This generates a schema that can be used by a JSON schema validator:

{
"title": "Form data",
"description": "A form submission",
"type": "object",
"properties": {
"username": { "type": "string", "minLength": 5 },
"age": { "type": "integer", "title": "Username" },
"city": {
"type": "string",
"minLength": 1,
"enum": [ "Gothenburg", "Stockholm" ]
},
"vegetarian": { "type": "boolean", "title": "Vegetarian" },
"interests": {
"type": "array",
"title": "Interests",
"items": { "type": "string", "title": "Interests" },
"minItems": 0
},
"profession": {
"type": "object",
"title": "Profession",
"properties": {
"workplace": { "type": "string", "title": "Workplace" },
"label": { "type": "string", "title": "Title" }
},
"required": []
}
},
"required": [ "username", "city" ]
}

Notice that:

  • The validators we defined above (minLength and allowedValues) on our components are part of the schema.
  • The interests multiple field is interpreted as an array.
  • Our group component is properly translated to an object inside of the schema.

Generating a schema for each form part

If you have forms with multiple parts you might need to validate each part in isolation.

import { generatePartSchemas } from "@fab4m/fab4m";
const schemas = generatePartSchemas(form);

This will give you an array of schemas, one for each form part in your form.

Using your schema

Fab4m doesn't provide a JSON Schema validator of it's own, you are free to choose any validator you like. The AJV validator for javascript is an excellent choice in js environments.

When is this useful?

Having a JSON schema readily available for any form means that you can always validate the input from any form anywhere where you can parse a JSON schema.

A note about rules and variants

Fab4m provides advanced features in the form of Rules and Variants. We generate a schema based on the data when using these features to avoid generating very complex JSON Schemas. Check documentation on rules and variants to see how it works.