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. Theitems
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:
{
"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 theenctype
property. All compliant implementations of this specification MUST support theapplication/x-www-form-urlencoded
format. They SHOULD also support theapplication/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 associatedlink
object, can be used to formulate and execute a state transition. If the value ofhref
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 theproperties
) associated with the samelink
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 ofname
MUST be a valid JSON string.When the
name
property appears in aproperties
collection associated with alink
object, the value of thename
field is used as the parameter identifier when composing a query or body string to send with the request. If the value of thename
property is invalid, un-parseable, or missing, thatproperty
SHOULD be ignored when composing a request query or body string.Then the
name
property appears in alink
ormetadata
object, the value of thename
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 thevalue
property of th associated object. Rules for validpattern
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. Eachproperty
object describes a parameter for the state transition associatedlink
element. This is an OPTIONAL collection. If the array is missing or empty, theproperties
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 associatedproperty
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 thereadonly
property is not understood by the recipient, the assumed value ofreadonly
is"false"
. -
required
-
This is a boolean property which indicates whether the
value
property of the associatedproperty
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 therequired
property is not understood by the recipient, the assumed value ofrequired
is"false"
. -
rel
-
The value of the
rel
property is a set of space-separated tokens that represent metadata about the associatedlink
object. There are several sources of validrel
values (see [IANA-LINKRELS]) and rules for creating your own validrel
values (see [RFC8288]). If the value ofrel
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. Theschema
property is associated with anitem
object. The contents of theschema
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 ofschema
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 oftags
property is empty or un-parsable, it SHOULD be ignored. If any of the tokens within thetags
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 oftitle
is plain text. -
type
-
The
type
property indicates a general type name associated with theproperty
oritem
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 oftype
can be used to indicate data types (string, boolean, integer, date-time, email, etc.). When it appears in anitem
object, the value oftype
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 associatedmetadata
orproperty
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:
-
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.