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
- 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."
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. Theitemscollection 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:
{
"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.
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
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.
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.
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.
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 theenctypeproperty. All compliant implementations of this specification MUST support theapplication/x-www-form-urlencodedformat. They SHOULD also support theapplication/json(see [RFC7159]) format and MAY support other formats. -
href -
The
hrefproperty MUST have a value that is a valid URL ([RFC3986]). This property, along with other properties of the associatedlinkobject, can be used to formulate and execute a state transition. If the value ofhrefis 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
idvalues 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 theproperties) associated with the samelinkobject. 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
nameproperty holds the general, non-unique name of the associated object. The value ofnameMUST be a valid JSON string.When the
nameproperty appears in apropertiescollection associated with alinkobject, the value of thenamefield is used as the parameter identifier when composing a query or body string to send with the request. If the value of thenameproperty is invalid, un-parseable, or missing, thatpropertySHOULD be ignored when composing a request query or body string.Then the
nameproperty appears in alinkormetadataobject, the value of thenamefield represents a non-unique identifier for the associated object. -
pattern -
The value of the
patternproperty is a regular expression string to be applied to thevalueproperty of th associated object. Rules for validpatternvalues 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
propertyobjects. Eachpropertyobject describes a parameter for the state transition associatedlinkelement. This is an OPTIONAL collection. If the array is missing or empty, thepropertiescollection 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
valueproperty of the associatedpropertyobject 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 thereadonlyproperty is not understood by the recipient, the assumed value ofreadonlyis"false". -
required -
This is a boolean property which indicates whether the
valueproperty of the associatedpropertyobject 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 therequiredproperty is not understood by the recipient, the assumed value ofrequiredis"false". -
rel -
The value of the
relproperty is a set of space-separated tokens that represent metadata about the associatedlinkobject. There are several sources of validrelvalues (see [IANA-LINKRELS]) and rules for creating your own validrelvalues (see [RFC8288]). If the value ofrelis empty, un-parseable, or not understood it SHOULD be ignored. -
schema -
The value of the
schemaproperty represents a pointer to a schema document that can be used to describe (and possibly validate) the message. Theschemaproperty is associated with anitemobject. The contents of theschemaproperty 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 ofschemais 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
tagsproperty. 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 oftagsproperty is empty or un-parsable, it SHOULD be ignored. If any of the tokens within thetagsvalue are not understood, those tokens SHOULD be ignored. -
title -
This property represents advisory information for the
propertyobject, such as would be appropriate for a tooltip or some other display. The value oftitleis plain text. -
type -
The
typeproperty indicates a general type name associated with thepropertyoritemobject. It MUST be a valid JSON string and MUST NOT contain any space characters. This is an OPTIONAL property.When it appears within a
propertyobject, the value oftypecan be used to indicate data types (string, boolean, integer, date-time, email, etc.). When it appears in anitemobject, the value oftypecan be used to indicate object types (customer, product, location, etc.).If the value of
typeis empty or un-parseable, it SHOULD be ignored. -
value -
The contents of the
valueproperty represent the value of the associatedmetadataorpropertyobject. 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:
-
No existing properties or objects are removed.
-
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).
-
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
-
[DABGWA] Mike Amundsen, "Design and Build Great Web APIs", 2020, https://pragprog.com/book/maapis/design-and-build-great-web-apis
-
[KAY2003] Dr. Alan Kay, "Clarification of "object-oriented", July 2003 (email), http://www.purl.org/stefan_ram/pub/doc_kay_oop_en
-
[REPO] Github, "PRAG-JSON", https://github.com/mamund/prag-json
-
[RFC2119] S. Bradner, "Key words for use in RFCs to Indicate Requirement Levels", March 1997, http://tools.ietf.org/html/rfc2119
-
[RFC3986] Berners-Lee, Fielding, Masinter,"Uniform Resource Identifier (URI): Generic Syntax", 2005, https://tools.ietf.org/html/rfc3986
-
[RFC7159] Tim Bray, "The JavaScript Object Notation (JSON) Data Interchange Format", March 2014, https://tools.ietf.org/html/rfc7159
-
[RFC8288] Mark Nottingham, "Web Linking", Object 2017, https://tools.ietf.org/html/rfc8288
-
[HTML5] HTML Living Standard, https://html.spec.whatwg.org/multipage/
-
[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
-
[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
-
[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
-
[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
-
[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
-
[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
-
[IANA-METHODS] "Hypertext Transfer Protocol (HTTP) Method Registry", April 2017, https://www.iana.org/assignments/http-methods/http-methods.xhtml
-
[IANA-MEDIATYPES] "Media Types", December 2019, https://www.iana.org/assignments/media-types/media-types.xhtml
-
[IANA-LINKRELS] "Link Relations", November 2019, https://www.iana.org/assignments/link-relations/link-relations.xhtml
-
[JSON-SCHEMA] "JSON Schema Specification", September 2019, https://json-schema.org/specification.html
-
[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.