Status

Doc Status

Working Draft — Only experimental and ‘proof-of-concept’ apps should be built on this unstable draft.

Proposed IANA Registrations

application/vnd.prag+json

Repository

https://github.com/mamund/prag-json

Sample Implementation

NA

Last Updated

2021-06-12

Summary

This document describes a simple media type designed to make it easy to render and parse hypermedia-aware representations. The format was created for the book "Design and Build Great Web APIs" ([DABGWA]).

Motivation

PRAG-JSON was designed to mimic the low-barrier of entry and high usability found in HTML ([HTML5]). Hypermedia-aware formats like HTML are one of the key reasons the Web become so widespread so quickly. It tapped into the ability to link documents together quickly and easily without much ceremony or engineering skills. It is hoped that PRAG-JSON will show how easy it is to create and use an application-level computer messaging format that supports a high degree of loose coupling and extreme late binding ([KAY2003]).

PRAG-JSON was designed to compliment the book "Design and Build Great Web APIs' ([DABGWA]). This book is a collection of lessons and common practices aimed to help the reader through the process of creating hypermedia-style APIs quickly and easily.

Another key motivator for the design of PRAG-JSON is to create web-based hypermedia format that works well in machine-to-machine (M2M) interactions. The foramt is simple in structure (metadata, links, items) and all the key elements support the use of unique in-document identifiers (id). These structure elements make is easy to associate data and actions from semantic profiles with exact elements within the response representation — an important key to successful M2M processing of content w/o relying on inference or other AI/ML support.

Updates

There is an open source repository [REPO] for this specification. Readers are encouraged to submit updates via the repository any time.

Compliance

An implementation (client or server) of this specification is not compliant if it fails to satisfy one or more of the MUST or REQUIRED elements. An implementation that satisfies all the MUST and REQUIRED elements as well as all the SHOULD and RECOMMENDED elements is said to be "unconditionally compliant"; one that satisfies all the MUST and REQUIRED elements but not all the SHOULD and RECOMMENDED elements is said to be "conditionally compliant."

RFC2119 Words

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in [RFC2119].

The PRAG-JSON Media Type

The PRAG-JSON media type is a simple JSON [RFC7159] document that contains runtime status information about network resources on the Web. PRAG-JSON has three root elements;

  • metadata : Contains an array of message metadata

  • links : Contains an array of simple web links and rich forms for navigating the application space and modifying it’s state

  • items : Contains an array of data items. The items collection represents the data associated with the network resource.

This media type can be used to provide dynamic representations of application state at runtime.

Example PRAG-JSON document

Below is a sample PRAG-JSON document example:

Sample PRAG-JSON document.
{
  "metadata" : [
    {"name" : "title", "value" : "BigCo Onboarding"},
    {"name" : "author", "value" : "Mike Amundsen"},
    {"name" : "updated", "value" : "2020-03-01"}
  ],
  "links" : [
    {
      "id" : "q1w2e",
      "rel" : "home",
      "name" : "home",
      "href" : "http://api.example.org/",
      "title" : "Home Page",
      "method" : "GET",
      "properties" : [
        {"name" : "filter", "value" : ""}
      ]
    }
  ],
  "items" : [
    {
      "id" : "za1xs2cd3",
      "type": "wip",
      "schema" : "api.example.org/schemas/wip.json",
      links : [
        {
          "id" : "q1w2e3r4"
          "name" : "item",
          "href" : "http://api.example.org/q1w2e3r4",
          "title" : "Read Item",
          "method" : "GET",
          "properties": []
        }
      ],
      "wipIdentifier" : "q1w2e3r4",
      "customerIdentifier" : "w2e3r4t5",
      "accountIdentifier" : "e3r4t5y6",
      "activityIdentifier" : "r4t5y6u7",
      "givenName" : "Idara",
      "familyName" : "Adams",
      "email" : "idara.adams@example.org",
      "telephone" : "123.456.7890",
      "status" : "pending",
      "maxValue" : "5000",
      "discount" : "10"
    }
  ]
}

IANA Media Type Registration for PRAG-JSON

The media type identifier string for PRAG-JSON documents is: application/vnd.prag+json This SHOULD be used as part of the HTTP accept header when making a request for a PRAG-JSON document. It SHOULD appear as the HTTP content-type header when sending a response that contains a PRAG-JSON document.

Elements of a PRAG-JSON Document

All PRAG-JSON documents MUST be valid JSON documents. A well-formed PRAG-JSON document has three top-level objects: metadata, links and items. The following is a summary of the structure of the PRAG-JSON media type.

The metadata Element

The metadata element is meant to hold message-level information about the payload of the response. This might be individual data properties that describe the payload, references to other related content, etc. Anything that might be needed in order to improve the understanding of the payload itself. The role played by the metadata element in PRAG-JSON is similar to the role played by the meta tag in HTML5 ([HTML5-TAG]).

The metadata element is an array of anonymous JSON objects. The default properties of metadata objects that SHOULD appear are name and value. Possible additional properties that MAY be part of a metadata object include: id, type, title, tags, href and others. Other properties not defined by this specification MAY appear as well.

Sample metadata object
{
  "name" : "".
  "value" : "",
  "id" : "",
  "type" : "",
  "title" : "",
  "tags" : "",
  "href" : ""
}

The metadata element SHOULD NOT contain any link or item elements as they are meant to appear in their own collection.

The links element contains any links and/or forms associated with the PRAG-JSON document. The links collection is an array of anonymous JSON link objects. These link objects are designed to carry complete details on Web navigation between resources including any protocol methods, arguments, and so forth. Any time the message needs to render a navigation or state change, this should appear as a link object. The links object plays a role in PRAG-JSON similar to HTML5’s link (HTML5-LINK), a (HTML5-A), and form (HTML5-FORM) tags.

The default properties of a link object that SHOULD appear are: name, href, method, and properties. Additional properties that MAY appear are: id, title, rel, tags, type, and enctype. Other properties not defined by this specification MAY appear as well.

Sample link object
{
  "id" : "".
  "name" : "",
  "href" : "",
  "title" : "",
  "type" : "".
  "rel" : "",
  "tags" : "",
  "enctype" : "",
  "method" : "",
  "properties" : [
    {"name" : "", "value" : ""}
  ]
}

The properties Array

The properties array within a link object contains one or more anonymous property objects. A property object SHOULD have name and value properties. It MAY have additional properties including id, title, required, readonly, pattern, type, and tags. Other properties not defined by this specification MAY appear as well. The role the property object plays in PRAG-JSON is similar HTML5’s input (HTML5-INPUT) element.

Sample property object
{
  "id", : "",
  "name" : "",
  "value" : "",
  "title" : "",
  "required" : "[true|false]",
  "readonly" : "[true|false]",
  "pattern" : "",
  "type" : "",
  "tags" : ""
}

The links element SHOULD NOT contain any metadata or +item elements as they are meant to appear in their own collection.

The items Element

The item element contains one or more data items that represent the state of the requested resource. The items collection is an array of anonymous JSON arbitrary objects. The items collection SHOULD contain a homogeneous JSON objects (e.g. all customer objects) but MAY contain a heterogeneous collection of objects.

Each item object SHOULD have id, type, and schema properties and MAY have any number of additional properties. The data for an item MAY be a set of properties at the "top" level or MAY be nested within a single named code (e.g. graph or data, etc. Each item object is essentially a graph arbitrary depth and complexity. The schema property of an item SHOULD provide enough information to allow message-handlers to properly parse the item.

Sample item object
{
  "id" : "",
  "type" : "",
  "schema" : "",
  "links" : [...]
  ...
}

The schema property SHOULD point to a JSON-Schema (JSON-SCHEMA) document but MAY point to some other document.

An item object MAY also include a single links collection. This links collection within an item object follows the same rules as the top-level links collection (see above).

PRAG-JSON Properties

Below is a list of valid PRAG-JSON properties defined in this specification. These properties MAY appear in more than one place within a valid PRAG-JSON message.

enctype

This property represents the media type to use when encoding a mesage body to be sent during a state transition. The default value for this field is application/x-www-form-urlencoded (see [FORM-ENCODED]). However, other valid media type string ([IANA-MEDIATYPES]) MAY appear in the enctype property. All compliant implementations of this specification MUST support the application/x-www-form-urlencoded format. They SHOULD also support the application/json (see [RFC7159]) format and MAY support other formats.

href

The href property MUST have a value that is a valid URL ([RFC3986]). This property, along with other properties of the associated link object, can be used to formulate and execute a state transition. If the value of href is empty or not understood by the recpient, it SHOULD be ignored.

id

This property specifies its object’s unique identifier. The value MUST be unique amongst all the id values in the document and must contain at least one character. The value MUST NOT contain any space characters.

method

This property specifies the HTTP method the client SHOULD use when sending a request using the href (and possibly the properties) associated with the same link object. Any valid HTTP method (see IANA-METHODS) is allowed. If the value is empty or is not understood by the client, the value MUST be treated if it is set to "GET".

name

The name property holds the general, non-unique name of the associated object. The value of name MUST be a valid JSON string.

When the name property appears in a properties collection associated with a link object, the value of the name field is used as the parameter identifier when composing a query or body string to send with the request. If the value of the name property is invalid, un-parseable, or missing, that property SHOULD be ignored when composing a request query or body string.

Then the name property appears in a link or metadata object, the value of the name field represents a non-unique identifier for the associated object.

pattern

The value of the pattern property is a regular expression string to be applied to the value property of th associated object. Rules for valid pattern values are the same as the HTML5 pattern attribute [HTML5-PATTERN]. This is an OPTIONAL element. If this attribute missing, is set to empty, or is unparseable , it SHOULD be ignored.

properties

This is an array of one or more anonymous property objects. Each property object describes a parameter for the state transition associated link element. This is an OPTIONAL collection. If the array is missing or empty, the properties collection MUST be treated as an empty set of parameters — meaning that the transition is meant to be executed without passing any parameters.

readonly

This is a boolean property which indicates whether the value property of the associated property object is editable. Valid values are "true" and "false". If this property is missing from the object, is set to any other value than "true" or "false", or if the value of the readonly property is not understood by the recipient, the assumed value of readonly is "false".

required

This is a boolean property which indicates whether the value property of the associated property object must be set to a non-empty value. Valid values are "true" and "false". If this property is missing from the object, is set to any other value than "true" or "false", or if the value of the required property is not understood by the recipient, the assumed value of required is "false".

rel

The value of the rel property is a set of space-separated tokens that represent metadata about the associated link object. There are several sources of valid rel values (see [IANA-LINKRELS]) and rules for creating your own valid rel values (see [RFC8288]). If the value of rel is empty, un-parseable, or not understood it SHOULD be ignored.

schema

The value of the schema property represents a pointer to a schema document that can be used to describe (and possibly validate) the message. The schema property is associated with an item object. The contents of the schema property is a valid URL that, when dereferenced, returns a schema document. By default, the type of schema document returned SHOULD be in JSON-Schema format ([JSON-SCHEMA]) but other formats MAY be returned instead. This is an OPTIONAL field. If the value of schema is empty or un-parseable, it SHOULD be ignored.

tags

This property, when it appears, contains a value that is a set of space-separated tokens representing the various classifications to which the associated object belongs. There are no additional restrictions on the tokens that MAY appear in the tags property. Representation designers are encouraged to use values that describe the nature of the content (noun) rather than the intended actions associated with the content (verb). If the value of tags property is empty or un-parsable, it SHOULD be ignored. If any of the tokens within the tags value are not understood, those tokens SHOULD be ignored.

title

This property represents advisory information for the property object, such as would be appropriate for a tooltip or some other display. The value of title is plain text.

type

The type property indicates a general type name associated with the property or item object. It MUST be a valid JSON string and MUST NOT contain any space characters. This is an OPTIONAL property.

When it appears within a property object, the value of type can be used to indicate data types (string, boolean, integer, date-time, email, etc.). When it appears in an item object, the value of type can be used to indicate object types (customer, product, location, etc.).

If the value of type is empty or un-parseable, it SHOULD be ignored.

value

The contents of the value property represent the value of the associated metadata or property object. This MUST be a valid JSON string. It MAY be an empty string. There are no other restrictions on the contents of this property.

Extending the PRAG-JSON Format

Authors can extend the PRAG-JSON media type as long as the following rules are observed:

  1. No existing properties or objects are removed.

  2. No existing properties or objects or the list of valid values are altered in a way that is non-backward compatible (e.g. changes MUST NOT break existing implementations that adhere to this specification).

  3. All new properties or objects are treated as OPTIONAL (e.g. no new REQUIRED elements are introduced in an extension).

Warning

Authors should be aware that a future version of this specification MAY add new elements and should take care that any extensions are implemented in a way that reduces the likelihood that a future version of this specification is in conflict with your extension.

References

  1. [DABGWA] Mike Amundsen, "Design and Build Great Web APIs", 2020, https://pragprog.com/book/maapis/design-and-build-great-web-apis

  2. [KAY2003] Dr. Alan Kay, "Clarification of "object-oriented", July 2003 (email), http://www.purl.org/stefan_ram/pub/doc_kay_oop_en

  3. [REPO] Github, "PRAG-JSON", https://github.com/mamund/prag-json

  4. [RFC2119] S. Bradner, "Key words for use in RFCs to Indicate Requirement Levels", March 1997, http://tools.ietf.org/html/rfc2119

  5. [RFC3986] Berners-Lee, Fielding, Masinter,"Uniform Resource Identifier (URI): Generic Syntax", 2005, https://tools.ietf.org/html/rfc3986

  6. [RFC7159] Tim Bray, "The JavaScript Object Notation (JSON) Data Interchange Format", March 2014, https://tools.ietf.org/html/rfc7159

  7. [RFC8288] Mark Nottingham, "Web Linking", Object 2017, https://tools.ietf.org/html/rfc8288

  8. [HTML5] HTML Living Standard, https://html.spec.whatwg.org/multipage/

  9. [HTML5-A] Ian Hickson, Ed., "HTML5: Edition for Web Authors", 2011, https://www.w3.org/TR/2011/WD-html5-author-20110705/spec.html#the-a-element

  10. [HTML5-FORM] Ian Hickson, Ed., "HTML5: Edition for Web Authors", 2011, https://www.w3.org/TR/2011/WD-html5-author-20110705/spec.html#the-form-element

  11. [HTML5-INPUT] Ian Hickson, Ed., "HTML5: Edition for Web Authors", 2011, https://www.w3.org/TR/2011/WD-html5-author-20110705/spec.html#the-input-element

  12. [HTML5-LINK] Ian HIckson, Ed., "HTML5: Edition for Web Authors", 2011, https://www.w3.org/TR/2011/WD-html5-author-20110705/spec.html#the-link-element

  13. [HTML5-PATTERN] Ian Hickson, Ed. et al, HTML5: Edition for Web Authors", 2011, https://www.w3.org/TR/2011/WD-html5-author-20110705/spec.html#the-pattern-attribute

  14. [HTML5-TAG] Ian Hickson, Ed., "HTML5: Edition for Web Authors", 2011, https://www.w3.org/TR/2011/WD-html5-author-20110809/the-meta-element.html

  15. [IANA-METHODS] "Hypertext Transfer Protocol (HTTP) Method Registry", April 2017, https://www.iana.org/assignments/http-methods/http-methods.xhtml

  16. [IANA-MEDIATYPES] "Media Types", December 2019, https://www.iana.org/assignments/media-types/media-types.xhtml

  17. [IANA-LINKRELS] "Link Relations", November 2019, https://www.iana.org/assignments/link-relations/link-relations.xhtml

  18. [JSON-SCHEMA] "JSON Schema Specification", September 2019, https://json-schema.org/specification.html

  19. [FORM-ENCODED] https://www.iana.org/assignments/media-types/application/x-www-form-urlencoded

Acknowledgements

I thank the everyone who helped contribute to this specification.