Hyperlinks

handling links defined in JSON Schema
The demos on this page use the following JavaScript files:
  • jsonary.js - the core Jsonary library
  • renderers/basic.jsonary.js - a default set of renderers, that look similar to plain JSON
  • renderers/list-schemas.js - annotates the data with schema titles
  • renderers/list-links.js - lists the hyper-links for the data

Defining a hyperlink

One of the many wonders of JSON Schemas is their ability to define hyperlinks on the data that they describe.

These are defined using the links keyword in schemas. Links are specified as an array of Link Description Objects, like in this example schema:

{
	"title": "Schema with links",
	"links": [
		{
			"href": "home.json",
			"rel": "home"
		},
		{
			"href": "page2.json",
			"rel": "next"
		}
	]
}

"Well OK," you say, "but the URIs are fixed! You'll need a different schema for every bit of data!".

That's a good point. Luckily for us, JSON Schema has a way around this. The URI specified in the href property is a template, which is filled with values from the instance data.

For example, let's look at this data: (data-list.json)

[
	{
		"id": 12345,
		"content": "foo"
	},
	{
		"id": 99999,
		"content": "bar"
	}
]

We would like to define a link on each of the items in that array, pointing to comments on that item. The URI of the link should be "http://example.com/items/{id}/comments", where {id} is replaced by the "id" property from the data.

Actually, that is exactly the syntax we need to use. So let's take this schema: (schema-list.json)

{
	"title": "Adaptive links",
	"items": {
		"title": "Sub-schema",
		"links": [
			{
				"href": "http://example.com/items/{id}/comments",
				"rel": "comments"
			}
		]
	}
}

And let's render our item:click to run

Hopefully, next to the schema titles annotating the data, you should see some links, labelled "comments" according to the rel value.

If you select these links, you should see a popup containing the URI of the link that you clicked. The URIs are different for the two items, due to their different values for "id".

Submitting data

Hyperlinks in JSON Schema can define data to be submitted with the link. The following properties are all optional:

  • schema - specifies the form the data should take, as a JSON Schema.
  • method - the method (GET/POST/etc.) with which the link should be accessed. Defaults to "GET".
  • encType - the encoding method for the data.

Any of these options can be omitted.

For example, here is a link definition that defines some data: (schema-link.json)

{
	"title": "Example schema",
	"links": [
		{
			"href": "mirror.php",
			"rel": "example",
			"method": "POST",
			"enctype": "application/x-www-form-urlencoded",
			"schema": {
				"type": "object",
				"properties": {
					"num": {"type": "integer"},
					"str": {"type": "string"}
				},
				"required": ["num", "str"],
				"additionalProperties": {"type": "boolean"}
			}
		}
	]
}

Let's take a look at what an instance described by that schema might look like:

When you click the link, a prompt should appear in which you can edit some data to submit. The response (from mirror.php) will be shown below:

When you submit the link data, you should (hopefully) see the data returned by mirror.php, which includes the POST data.

You may notice that the POST data is formatted exactly like a query string in a URL. This is the encoding defined by the media type application/x-www-form-urlencoded, and it is the default encoding when using HTML forms.

Submitting JSON data

When using the application/x-www-form-urlencoding encoding, all the data is bundled up into a query string, and therefore loses all type information. The number 2 is indistinguisable from the string "2".

Fortunately, this is not the only encoding we can use. We can use any media type, including application/json: (schema-link-json.json)

{
	"title": "Example schema",
	"links": [
		{
			"href": "mirror.php?some=parameters&because=why_not",
			"rel": "example",
			"method": "POST",
			"encType": "application/json",
			"schema": {
				"type": "object",
				"properties": {
					"num": {"type": "integer"},
					"str": {"type": "string"}
				},
				"required": ["num", "str"],
				"additionalProperties": {"type": "boolean"}
			}
		}
	]
}

This is actually the default value of encType for POST links in JSON Schema (if you are making GET requests, then only application/x-www-form-urlencoded is available). Let's look at what happens when we use that link:

The response from mirror.php will be shown below:

As you can hopefully see, the data being sent as the POST body is now encoded as JSON.

Please note: submitting JSON data as above is not the same as submitting JSON data as a string value in an HTML form. Submitting JSON data as an input with name "jsonData" would end up POSTing something like this:

jsonData=%7B%22num%22%3A0%2C%22str%22%3A%22value%22%7D