This guide explains how JSON Schema is used within our form system, based on react-jsonschema-form v1.6 and the JSON Schema specification. JSON Schema defines the expected data structure, types, and validation rules for the form data.
A typical JSON schema defines an object with properties corresponding to form fields.
{
"type": "object",
"properties": {
"fieldName": {
"type": "string",
"title": "User-Friendly Field Name",
"description": "Help text for the user."
},
"anotherField": {
"type": "number",
"title": "Another Field"
}
}
}
We utilize several standard JSON Schema keywords:
type: Specifies the data type for a field (string, number, integer, boolean, array, object).title: A user-friendly label displayed for the field.
"title": "common.fieldLabel") and are automatically looked up in the internationalization files.description: Help text or hints displayed to the user, often as a tooltip or subtitle.properties: Defines the fields within an object type schema.required: An array of strings listing the property names (within the current object) that must have a value.enum: An array of predefined allowed values for a field. Often used for dropdowns or radio buttons.enumNames: An array of user-friendly labels corresponding to the values in the enum array. If omitted, the enum values themselves are displayed.
title, values in this array are treated as translation keys.default: A default value to pre-populate the field with.items: Defines the schema for elements within an array type field. Can be a single schema (for uniform arrays) or an array of schemas (for tuple-like arrays).minItems: Minimum number of items required in an array.format: Provides semantic meaning to string types (e.g., date-time, email, uri, json). In our case, json is used with the JsonEditor widget.dependencies: Defines conditional logic where the presence or value of one field affects the requirements or schema of others.oneOf: Used within dependencies, this allows specifying different schema variations based on the value of a controlling field.This example shows several keywords in action:
{
"type": "object",
"title": "Data source",
"properties": {
"service": {
"type": "string",
"title": "Metadata service instance name",
"description": "form.hints.eprServiceInstance"
},
"applicationSelection": {
"type": "string",
"title": "Show endpoints from",
"enum": ["Single", "Multi"], // Allowed internal values
"enumNames": ["Single application", "Multiple applications"], // Displayed labels
"default": "Single"
},
// ... other properties
},
"required": ["service"], // 'service' must be provided
"dependencies": {
"applicationSelection": { // Logic depends on 'applicationSelection'
"oneOf": [
{ // Schema variation when applicationSelection is 'Single'
"properties": {
"applicationSelection": { "enum": ["Single"] },
"applicationName": {
"type": "string",
"title": "Application",
"description": "Only display endpoints that belong to this application",
"enum": ["__IGNORE_VALUE__"], // Initial/placeholder enum
"enumNames": ["All"]
},
// ... more single-application specific fields
}
},
{ // Schema variation when applicationSelection is 'Multi'
"properties": {
"applicationSelection": { "enum": ["Multi"] },
"applications": {
"type": "string", // Often used with multi-select widget
"title": "Application",
"description": "Only display endpoints that belong to applications"
}
}
}
]
}
}
}
enum and enumNames provide choices for applicationSelection.required makes the service field mandatory.dependencies combined with oneOf changes the available fields (applicationName vs. applications) based on the applicationSelection value. The empty enum for applicationName is typical; it gets populated dynamically by UI Schema transformations (covered in a separate guide).{
"columns": {
"type": "array",
"title": "Columns",
"minItems": 1, // At least one column is required
"items": { // Defines the schema for each object in the 'columns' array
"type": "object",
"properties": {
"display": {
"type": "string",
"title": "Column title"
},
"cellType": {
"type": "string",
"title": "Cell type",
"enum": ["text", "icon", "action", /* ... */],
"default": "text"
},
// ... other column properties
},
"required": ["display"] // Each column must have a title
}
}
}
This defines an array named columns, where each element must be an object conforming to the items schema, requiring at least a display property.
For more advanced schema design, refer to the JSON Schema specification and the base library documentation. The real power comes from combining this schema definition with the UI Schema and Transformations, covered in their respective guides.