The what and why of JSON(Schema)

June 22, 2015 | 6 min Read

JSONForms is an AngularJS-based framework to simplify the creation of forms for data entry and edit in web applications. It allows to declaratively define the content and layout of a form and to embed the form into your HTML with one simple tag. If you would like to know more about JSONForms here is an introduction. Also the JSONForms homepage is a good starting point..

In this post we’ll first have a look at JSON schema: what it is, and what its applications are. We then illustrate how it relates to JSONForms and close with a small example demonstrating JSONForms.

What is JSONSchema?

While JSON is currently, undeniably, one of the most popular formats for exchanging data on the web, its meta-description JSONSchema isn’t yet as popular and widely known, but this is changing already.

In short, the main use of JSON schema is to describe the structure and validation constraints of your JSON documents. In contrast to XML, which allows you to create custom dialects, JSON is not as generalizable and flexible, however, it doesn’t want to be. JSON is meant to describe hierarchical data structures in a concise way, a task in which XML is generally considered to be less appropriate than JSON due to the verbose syntax.

A typical JSON schema for a user entity might look as follows:

user-schema.json

{
  "type": "object",
  "properties": {
    "firstName": {
      "type": "string"
    },
    "lastName": {
      "type": "string"
    },
    "email": {
      "type": "string",
      "format": "email"
    },
    "gender": {
      "type": "string",
      "enum": ["Male", "Female"]
    },
    "active": {
      "type": "boolean"
    },
    "weight": {
      "type": "number"
    },
    "height": {
      "type": "integer"
    },
    "dateOfBirth": {
      "type": "string",
      "format": "date-time"
    }
  },
  "required": [ "firstName", "email" ],
  "additionalProperties": false
}

Most of this should be self-explanatory: the user is an object with different properties where each one has a name and a type. The enum, format and required keywords are part of the Schema Validation specification:

  • enum expects an array of valid values
  • format describes a semantic validation constraint a value must fulfill. Other formats include email, hostname or ipv4
  • required lists all mandatory properties of a user, all others properties are optional

A valid instance that validates against this schema is given below:

{
  "firstName": "John",
  "email": "

[email protected]

"
}

At the time of writing (June 2015), the JSON schema standard isn’t yet finalized. The current specification is v4 and is split across different documents

The JSON Schema core

The core mainly defines terminology and describes common mechanisms such as URI resolutions scopes and dereferencing.

It also introduces the $schema keyword that identifies the used JSON Schema version and defines the application/schema+json application type.

All related specifications, like the Schema Validation and Hyper-Schema, use the terminology defined in the core.

Schema validation

The schema validation specification is one purpose of JSON Schema and describes different keywords that may be utilized to put constraints on JSON instances. In the context of strings, examples for such keywords are minLength and maxLength.

Hyper-Schema

The Hyper-Schema specification describes hyperlink- and hypermedia- related keywords that may be used with JSON Schema, such as links, ref and href keywords.

The purpose of these keywords is to provide a common way of defining hyper-text and hyper-media references, since JSON Schema does not provide a native way of handling those. All hyper-text and hyper-media references happen by using encoded strings. An example taken from the specification that uses the links keyword looks like this:

{
  "title": "Written Article",
  "type": "object",
  "properties": {
    "id": {
      "title": "Article Identifier",
      "type": "number"
    },
    "title": {
      "title": "Article Title",
      "type": "string"
    },
    "authorId": {
      "type": "integer"
    },
    "imgData": {
      "title": "Article Illustration (small)",
      "type": "string",
      "media": {
        "binaryEncoding": "base64",
        "type": "image/png"
      }
    }
  },
  "required" : ["id", "title", "authorId"],
  "links": [
    {
      "rel": "full",
      "href": "{id}"
    },
    {
      "rel": "author",
      "href": "/user?id={authorId}"
    }
  ]
}

In the above example the links property is of special interest. It describes how the schema relates to valid instances. A link description consists of the rel and href keywords.

The value of the rel property indicates the name of the relation to the target resource while the href property is used as a template for a relative URI that can be used to obtain linked instance values.

In the above example this means if we would like to retrieve the author of an article, we would need to issue a (GET) request to the relative URI /user?id={authorId} where {authorId} will be replaced by the actual instance value.

The Hyper-Schema spec is likely to play a central role in JSONForms and we’ll come back to it in a future blog post.

Use in JSONForms

JSONForms, which we announced last week, relies heavily on the JSON and JSON Schema: for the description of your data it is making use of JSON schema while the UI schema is represented as regular JSON (for which we’ll define a schema later on).

For instance, if we’d like to model a widget that displays a user’s name as well as his/her height, we can do so by providing the following UI schema:

{
  "type": "HorizontalLayout",
  "elements": [
    {
      "type": "Control",
      "scope": {
        "$ref": "user-schema.json#/firstName"
      }
    },
    {
      "type": "Control",
      "scope": {
        "$ref": "user-schema.json#/gender"
      }
    }
  ]
}

The type property in the above UI schema describes how child elements will be laid out. In the case of the HorizontalLayout, all elements will be put side-by-side in a row.

The “Control” type of the contained children describes a widget that is bound to a specific property of a JSON instance.

The wiring happens by specifying a reference via the $ref keyword. The value of the $ref property must be a URI and must adhere the JSON Pointer syntax. This URI needs to resolve to a valid JSON value. In our case, we assumed that the user schema has been saved to a file called user-schema.json file, therefore we first need to specify the actual schema we want to point at.  Note that it would also be possible of course, that the user schema is obtained by other means. After that, a JSON Pointer follows which, in our cases, retrieves the firstName and the gender property within the user schema, respectively.

The rendered result is quite unspectacular, but it illustrates the essence of having automatically rendered forms just by providing the UI schema and the schema:

In case you want to play around with JSONForms you can already do so. We set-up a quick prototype for demo purposes, so you can get an impression of where JSONForms is heading.

If you would like to read more about JSONForms and how to get started with JSONForms, read on in the next blog post.

All feedback is appreciated, do not hesitate to contact us by Email, Twitter, Google+ or by commenting here!

Update: JSON Forms is now released regularly and a blog series on JSON Forms was just started introducing the features of JSON Forms based on one consistent example.

Guest Blog Post

Guest Author: Edgar Müller

Jonas, Maximilian & Philip

Jonas Helming, Maximilian Koegel and Philip Langer co-lead EclipseSource. They work as consultants and software engineers for building web-based and desktop-based tools. …