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.