Media types
Resources are represented by application/hal+json
[draft] objects. A HAL object consists of state properties, embedded resources (_embedded
), and links to other resources (_links
), according to the resource-specific documentation.
Response bodies
Except for OPTIONS
, HEAD
and DELETE
, all successful methods will return a HAL representation of the requested, created or modified resource. This choice of media type will (incorrectly) ignore the Accept
header, unless the requested media type is an available alternative. (This makes it possible to request the subscription collection as an application/opml+xml
outline.)
In the case of an error, the response of any method will be a JSON object with a property _status
whose value is an object with properties httpStatusCode
, httpStatusMessage
and details
, which is a string describing the situation. If there is an error while trying to POST
a specific resource, the returned object will also include, alongside the _status
property, all "required" state properties from the posted representation (only excluding those that are "write-only"), plus any property marked as _noduplicate
(see below).
Superfluous or missing request body
If a request body is submitted with an OPTIONS
, GET
, HEAD
or DELETE
request, the request body will be ignored.
If no request body is present for a POST
, PUT
or PATCH
request, the API will assume that the empty JSON object {}
was intended, which may or may not make the request valid according to the following rules.
Request body for POST
A POST
request body MUST be either:
- a representation of the desired resource as a JSON object that consists of all "required" state properties, any number of "optional" state properties, and an optional
_noduplicate
meta-property (see below); or - a JSON array of (only) such objects, representing any number of desired resources; or
- only when posting to the "subscriptions" collection, a valid OPML outline, in which case the header
Content-Type: application/opml+xml
MUST be set (see the "subscriptions" documentation for how OPML is interpreted).
If _noduplicate
is present, its value MUST be the key of a state property present in the representation. The API interprets this by denying the resource creation and returning 409 Conflict if there already is a resource with the attempted value for that property (even if it does not otherwise enforce uniqueness of that property).
Multi-post
If the body is a JSON array, the same functionality is achieved as if each member resource had been posted in an individual request. The request will return 200 OK unless a fatal error has occurred, even if no resources were actually created. The response body will be a JSON array of HAL or _status
objects. For the purpose of the _noduplicate
constraint, it may be assumed that such a multi-post array will always be processed in ascending index order.
For example, to attempt to create labels named "Science" and "Television", but only if they do not already exist, you could POST
the following JSON array to the "labels" collection:
[
{
"name": "Science",
"_noduplicate": "name"
},
{
"name": "Television",
"_noduplicate": "name"
}
]
It is not possible to create resources of different types in one request. Specifically, it is not possible to create a resource and at the same time create embedded subresources.
Request body for PUT
A PUT
request body MUST be a representation of the desired resource as a JSON object that consists of all "required" state properties and any number of "optional" state properties, and does not contain any "immutable" state properties. (If a property is both "required" and "immutable", PUT
is not possible.) Any "optional" properties omitted will be reset to their default value.
Request body for PATCH
A PATCH
request body MUST be either:
- a representation of the desired resource as a JSON object that consists of any number of "required" or "optional" state properties, and does not contain any "immutable" state properties; or
- only if the resource has capacity for embedding an array of subresources, a JSON object containing a single property
_witheach
(see below).
Any properties omitted will be left untouched. If an optional property is included with null
as its value, it will be reset to its default value as defined by the server.
Batch updating
By using the _witheach
syntax in a PATCH
request body, it is possible to perform the same update on all resources embedded in another resource (possibly obtained with selective query string parameters). For example, to archive a number of items, perform a PATCH
request on a URI representing the items in question (based on the ttzn:items
URI template), and supply the following JSON request body:
{
"_witheach": {
"ttzn:item": {
"method": "PATCH",
"data": {
"state": "archived"
}
}
}
}
Valid values for the method
property are, subject to acceptance by the target resource, "PUT"
, "PATCH"
and "DELETE"
. How to do other stuff with this syntax, like deleting ten subscriptions by ID (or even nesting _witheach
to only remove all tags from them), is left as an exercise for the API user!
Note 1: The server ensures the same functionality as though it had sent individual HTTP requests to each embedded resource. The actual implementation is, of course, more low-level.
Note 2: It is not possible to include _witheach
and state property updates in the same request. This is mainly because of error handling: it would be confusing for part of a PATCH
request to be successful. (This could definitely be solved, for example by some clever use of SQL transactions, but it's hardly worth it.)