Skip to content

JSON Schema

weili edited this page Jul 6, 2023 · 5 revisions

Intro

This is a living document to record various thoughts / considerations / attempts and structure of the JSON schema. It serves as a reference for contributors to the JSON schema and the thought processes that gave rise to the schema used today.

Guiding principles

  • Keep structure simple
  • Keep schema readable and easy to understand
  • Avoid ambiguous keys

The JSON schema

{
	"id": "my-form",
	"validationMode": "onTouched",
	"revalidationMode": "onChange",
	"sections": {
		"my-section": {
			"uiType": "section",
			"children": {
				"my-name": {
					"uiType": "text-field",
					"label": "Name",
					"className": "my-class-name",
					"validation": [
						{
							"required": true,
							"errorMessage": "My optional error message"
						},
						{
							"max": 25,
							"errorMessage": "Max 25 characters"
						}
					]
				},
				"my-age": {
					"uiType": "number-field",
					"label": "Age",
					"validation": [
						{
							"required": true
						},
						{
							"min": 1,
							"errorMessage": "Min. 1 year old"
						}
					]
				},
				"my-wrapper": {
					"uiType": "div",
					"className": "col-2",
					"children": {
						"my-text": {
							"uiType": "text-field",
							"label": "Something",
							"className": "my-css-class",
							"validation": [
								{
									"required": true
								}
							]
						}
					}
				}
			}
		}
	}
}

Unique key for each field

sections is an object by design and each individual field requires an unique key as a result. The key doubles as the id of the field and is used internally as the identifier of the field instance.

Field key naming considerations

For developers when developing new fields and need to define keys for the field, do avoid using HTML attributes. This is to avoid clashing with real HTML attributes when they are needed.

// bad
{
	"uiType": "my-field",
	"alt": "a value not intended for the alt tag" // alt is a valid HTML attribute
	
}
// good
{
	"uiType": "my-field",
	"somethingElse": "a value not intended for the alt tag"
}

Keys that prevent submission

Certain fields can have keys that prevent submission. These can be considered validation logic and should be included as part of validation array. E.g. text field can define max characters and should be within validation.

// bad
{
	"uiType": "text-field",
	"maxLength": 25
	
}
// good
{
	"uiType": "text-field",
	"validation": [
		{
			"max": 25,
			"errorMessage": "Max 25 characters"
		}
	]
}

Considerations

JSON schema standards

There was an intention to make the JSON schema standard-compliant. One candidate is the JSON Schema standards. Aside from the benefits described in the website, adhering to the standards will ease the learning curve to pick up our JSON schema and open up to available tools in their ecosystem (e.g. validator).

However after exploring further, it becomes apparent that it is not suitable for our use case.

As per their standards, the type of fields must be either string, number, boolean, array, object or null. In order to adhere to this, we will need to "guess" the intended field from the JSON provided. For example if a field is of number type, we can assume it is a number field or if it is an array of strings, it is probably a set of checkboxes / radio buttons / select field. As you can see, having an array of values already presents some sense of ambiguity and it will get more confusing when the fields get more complex. Granted it is possible to introduce an extra key to define what exactly is the field but that causes more confusions and defeats the intention to follow the standards in the first place.

From the way it is structured, it is more suited to define for the eventual submitted values. E.g. a group of checkboxes will submit as an array of strings while an email field will submit as a string. In contrast, we are using the JSON schema to define the structure of the form rather than the submitted values.