- Author
-
Cameron Bytheway <[email protected]>, Tim Shadel
- Status
-
Working Draft
- Last Updated
-
2024-11-18
- Proposed IANA Registrations
-
application/hyper+json
hyper+json is a JSON based hypermedia format designed for simplicity and flexibility.
hyper+json strives for simplicity:
-
Simple to understand
-
Simple to write
-
Simple to consume
-
Simple to extend
It also tries to be as familiar as possible to JSON users.
An implementation 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."
Note
|
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 RFC 2119. |
The most basic hyper+json resource is an object which MUST contain an href
:
{
"href": "/"
}
hyper+json resources can have arbitrary properties mixed with the hypermedia controls:
{
"href": "/users/cameron",
"name": "Cameron",
"addresses": {
"home": {
"street": "123 Fake St.",
"city": "Nowhere",
"country": "USA",
"zip": 12345
},
"work": { }
},
"likes": [
"hot-dogs",
"spoons",
"toasters"
]
}
A hypermedia link is represented as an object with a href
property. It MAY have any other properties as desired:
{
"href": "/users/cameron",
"name": "Cameron",
"friends": {
"href": "/users/cameron/friends",
"count": 123
},
"likes": [
{"href": "/likes/hot-dogs"},
{"href": "/likes/spoons"},
{"href": "/likes/toasters"}
]
}
Servers MAY use JSON Pointers prefixed with a #. If href
starts with # the pointer references a local property:
{
"href": "/users/cameron",
"name": "Cameron",
"first-name": {
"href": "#/name"
},
"status": {
"href": "/users/cameron/statuses#/0/text"
},
"status-updates": {
"href": "/users/cameron/statuses#/count"
}
}
{
"href": "/users/cameron/statuses",
"collection": [
{"text": "I'm happy!"},
{"text": "Kinda sad... :("}
],
"count": 2
}
A hypermedia form is represented as an object with an action
property. It SHOULD have a method
property that is specific to the protocol i.e. GET, POST, PUT, DELETE, etc for HTTP.
{
"href": "/users/cameron",
"name": "Cameron",
"update": {
"action": "/users/cameron",
"method": "PUT",
"input": {
"name": {
"type": "text",
"required": true,
"value": "Cameron"
}
}
}
}
The content-body when submitting the form in this example should be:
{ "name": "Tim" }
Clients SHOULD assume the acceptable type is application/json
, unless specified in the enctype
:
{
"href": "/users/cameron",
"name": "Cameron",
"update": {
"action": "/users/cameron",
"method": "PUT",
"enctype": "application/x-www-form-urlencoded",
"input": {
"name": {
"type": "text",
"required": true,
"value": "Cameron"
}
}
}
}
with the body:
name=Mike
A client SHOULD only submit forms that have understood content-types.
An input control belongs to a form element. It is represented as an object. It contains no required properties. It MAY include the following properties:
- type
-
Specifies the type of the input data. If the
type
is not set, a client SHOULD default to typetext
. hyper+json borrows the types specified by the HTML 5 input element specifies, along with the typeselect
. Servers MAY choose to add more types as needed. Clients SHOULD only handle input types they understand. - value
-
Specifies the current or default value of the input. If
value
is not set, clients SHOULD default tonull
.
Servers MAY choose to add more properties as needed. These properties SHOULD be specified in extensions.
By default, hyper+json resources are single documents. To address a collection of documents servers SHOULD use the collection
property. Any included properties in the root document are associated to the collection itself.
{
"href": "/users",
"collection": [
{"href": "/users/cameron"},
{"href": "/users/tim"},
{"href": "/users/mike"}
],
"count": 3
}
Servers MAY choose to paginate collection. They SHOULD use the next
and prev
links to provide pagination:
{
"href": "/users?page=1",
"collection": [
{"href": "/users/cameron"},
{"href": "/users/tim"},
{"href": "/users/mike"}
],
"next": {
"href": "/users?page=2"
}
}
{
"href": "/users?page=2",
"collection": [
{"href": "/users/ben"},
{"href": "/users/josh"}
],
"prev": {
"href": "/users?page=1"
}
}
Servers MAY use the data
property to wrap values and provide extra metadata about an object. Clients SHOULD be aware that any value MAY be wrapped.
Example usages include specifying a profile, specifying a label or deprecating a property.
{
"href": "/users/1",
"name": {
"profile": "https://schema.org/name",
"label": "Name",
"data": "Cameron"
},
"first-name": {
"deprecated": true,
"data": {
"href": "#/name"
}
}
}
{
"href": "http://example.org/users",
"collection": [
{"href": "http://example.org/users/1"},
{"href": "http://example.org/users/2"},
{"href": "http://example.org/users/3"}
]
}
{
"href": "http://example.org/users/1",
"name": "Cameron",
"favorites": {
"color": "red",
"food": ["bananas", "potatoes", "cheese"]
},
"update": {
"action": "http://example.org/users/1",
"method": "PUT",
"input": {
"name": {
"type": "text",
"required": true,
"value": "Cameron"
},
"color": {
"type": "select",
"options": [
{"value": "red"},
{"value": "blue"},
{"value": "green"}
]
},
"food": {
"type": "select",
"multiple": true,
"options": [
{"value": "bananas"},
{"value": "potatoes"},
{"value": "cheese"},
{"value": "carrots"}
]
}
}
}
}
This document describes the hyper+json markup vocabulary. Any extensions to the standard vocabulary MUST not redefine any objects (or their properties), arrays, properties, link relations, or data types defined in this document. Clients that do not recognize extensions to the standard vocabulary SHOULD ignore them.
The details of designing and implementing extensions is beyond the scope of this document.
Note
|
It is possible that future forward-compatible modifications to this specification will include new objects, arrays, properties, link-relations, and data types. Extension designers should take care to prevent future modifications from breaking or redefining those extensions. |