Specification and Interpretation

This is an informal specification of the JSON-ROA extension and how clients must interpret it.

We also provide some examples for illustration. These are mostly taken form the JSON-ROA Demonstration Application.

Table of Contents

General Properties

Semantic Versioning

JSON-ROA uses Semantic Versioning. The semantics apply to the JSON-ROA Object itself and precisely whether changes thereof would break JSON-ROA clients implemented for an earlier version. Experimental properties are excluded from this rule.

A client must evaluate the given semantic version and it must fail with an appropriate error if it is not compatible with the given major number. It may indicate discrepancies of the minor number but it must process the request.

The semantic version of JSON-ROA is strictly limited to JSON-ROA itself. It does not apply to the application.

The Content-Type

The JSON-ROA extension shall be present if and only if the resource is delivered with the content type application/json-roa+json.

The JSON-ROA Object

The JSON-ROA Object is located under the _json-roa key if the top level element is an object. If the top level element is an array the first element is a map with the _json-roa key and the corresponding map underneath.

In this sense, a given json-object can be extended by adding a _json-roa key including its object. A given json-array can be extended by placing an object which includes a _json-roa key and its corresponding object in the first position.

It is discouraged to use arrays as the outer most data structure. Maps are more flexible and can be extended in less obtrusive way.

A minimal valid JSON-ROA extension must contain the key version where the value must be formatted according to Semantic Versioning. See also the section Semantic Versioning.

It may further contain the keys relations, collection, name, and self-relation. See the relations object, the collection object, and the relation object for the specification of the corresponding values.

1
2
3
4
{ "_json-roa": { "version" : "1.0.0" }
  , "x": "some other data"
  , "y": 42
  , "z": false }
1
2
3
4
[ {"_json-roa": {"version" : "1.0.0" }},
  "some other data",
  42,
  false, ]

The Relations Object

The key relations introduces a relations object. The keys in the next level within are relation-identifiers and the corresponding object is a relation-object, see the section [The Relation Object][].

1
2
3
4
5
{"_json-roa" :
  {"version": "1.0.0",
    "relations": {
      "messages": {
        "href": "/messages/" }}}}

The Relation Identifier

The identifier of a relation is meant to be used in clients to dereference the relation object and in particular use the href-value therein. The example illustrates how to request the messages resource given a root resource with the JSON-ROA Ruby Client.

1
root.relation('messages').get()

The Relation Object

A relation is an object which must contain the key href. It may contain the keys embedded,name, methods, and relations. See the section Meta Relations for the interpretation of relations. See the section Embedding Resources for usage and interpretation of embedded.

1
2
3
{ "relations": 
  { "messages": 
    { "href": "/messages/" }}}
The Href Value

The value of the key href is a string and represents an URI according to RFC3986 Uniform Resource Identifier. It must at least contain a path segment. The values before the path segment are inferred form the current resource if they are not given. The URI may be templated according to RFC6570 URI Template.

The second example shows how values for templated parameters can be submitted with the JSON-ROA Ruby Client.

1
2
3
{ "relations": 
  { "message": 
    { "href": "/messages/{id}"}}}
1
2
root.relation('message') \
  .get('id' => '4e762513-d903-4228-b92c-da4f0cb3094b')
The Name Value

The name should not be used for technical purposes. The name is used, e.g. by the JSON-ROA Browser, to give a understandable output for the human user.

1
2
3
4
{ "relations": 
  { "message": 
    { "href": "/messages/{id}", 
      "name": "Message"}}}
The Methods Object

The methods object may contain the keys get, put, patch, post, and delete. Each value is an empty object at this time.

Clients should interpret the keys as the available HTTP-method to act on the given url respectively resource they address.

If the no methods are given, clients must assume that get and only get is available.

1
2
3
4
5
6
7
{ "relations": 
  { "messages": 
    { "href": "/messages/",
      "name": "Messages",
      "methods": 
        { "get": {},
          "post": {}}}}}
Meta Relations

A Relation Object can itself contain a Relations Object under the key relations. The primary use is to link to the corresponding resource documentation.

1
2
3
4
5
6
7
8
9
10
{"_json-roa" :
  {"version": "1.0.0",
    "relations": {
      "messages": {
        "href": "/messages/",
        "name": "Messages",
        "relations": {
          "messages-documentation": {
            "name": "API Messages Resource Documentation",
            "href": "/docs/index.html#messages" }}}}}}

The Collection Object

The collection object semantically links to a number of structurally equivalent resources. Conventionally only url paths ending with a slash , e.g. /tasks/, will contain a collection. This convention is apparently violated by many sites and even frameworks.

The collection object must contain a relations key which contains as described in the section relations object. It is suggested to use integers as keys which represent the index of the given link within the collection.

The collection can contain a next key with the value of a relation object with the following restriction: the included url may not be templated. Clients use next to iterate of a paginated collection. API providers should keep the search parameters between successive next link (with the exception of the parameter used for pagination if present).

Any of the following two conditions signals the end of the collection for a client:

  1. The relations object is empty.
  2. There is no next key.
1
2
3
4
5
6
7
8
9
{"_json-roa" :
  { "version": "1.0.0",
    "collection": 
      { "next": { "href": "/messages/?page=1" },
        "relations": 
          { "1": 
            { "href": "/messages/2f09edb9-5aec-460f-9e6a-5e9b980e8f05"}, 
            "2": 
            { "href": "/messages/4e762513-d903-4228-b92c-da4f0cb3094b"}}}}}

Embedding Resources

Embedding resources is an experimental proposal. There does not exist any implementation or proof of concept at this time. Any changes related to this feature do not warrant a lifting of the major number!

A Relation Object can contain the key embedded. The corresponding value map must be equal to the to JSON transformed response body given by requesting the resource with HTTP GET and receiving the representation of content-type application/json-roa+json. Therefore the following restrictions apply:

  1. The href value of the relation must not be a template url.
  2. The http get method must be applicable to the resource.

Handling of embedded resources must be completely transparent. I.e. clients must not depend on the existence of an embedded object. On the other hand are clients not required to honor embedded resources.

JSON-ROA does not define any technique how to negotiate respectively request embeddings. This is application and context dependent. A custom HTTP header seems to be appropriate for many cases.