Resource endpoints¶
All endpoints URLs are prefixed by the major version of the HTTP API (e.g /v1 for 1.4).
e.g. the URL for all the endpoints is structured as follows::
https://<server name>/<api MAJOR version>/<further instruction>
The full URL prefix will be implied throughout the rest of this document and it will only describe the <further instruction> part.
GET /{collection}¶
Requires authentication
Returns all records of the current user for this collection.
The returned value is a JSON mapping containing:
data
: the list of records, with exhaustive fields;
A Total-Records
response header indicates the total number of records
of the collection.
A Last-Modified
response header provides a human-readable (rounded to second)
of the current collection timestamp.
For cache and concurrency control, an ETag
response header gives the
value that consumers can provide in subsequent requests using If-Match
and If-None-Match
headers (see section about timestamps).
Request:
GET /articles HTTP/1.1
Accept: application/json
Authorization: Basic bWF0Og==
Host: localhost:8000
Response:
HTTP/1.1 200 OK
Access-Control-Allow-Origin: *
Access-Control-Expose-Headers: Backoff, Retry-After, Alert, Content-Length, ETag, Next-Page, Total-Records, Last-Modified
Content-Length: 436
Content-Type: application/json; charset=UTF-8
Date: Tue, 28 Apr 2015 12:08:11 GMT
Last-Modified: Mon, 12 Apr 2015 11:12:07 GMT
ETag: "1430222877724"
Total-Records: 2
{
"data": [
{
"id": "dc86afa9-a839-4ce1-ae02-3d538b75496f",
"last_modified": 1430222877724,
"title": "MoCo",
"url": "https://mozilla.com",
},
{
"id": "23160c47-27a5-41f6-9164-21d46141804d",
"last_modified": 1430140411480,
"title": "MoFo",
"url": "https://mozilla.org",
}
]
}
Filtering¶
Single value
/collection?field=value
Minimum and maximum
Prefix attribute name with min_
or max_
:
/collection?min_field=4000
Note
The lower and upper bounds are inclusive (i.e equivalent to greater or equal).
Note
lt_
and gt_
can also be used to exclude the bound.
Multiple values
Prefix attribute with in_
and provide comma-separated values.
/collection?in_status=1,2,3
Exclude
Prefix attribute name with not_
:
/collection?not_field=0
Exclude multiple values
Prefix attribute name with exclude_
:
/collection?exclude_field=0,1
Note
Will return an error if a field is unknown.
Note
The ETag
and Last-Modified
response headers will always be the same as
the unfiltered collection.
Sorting¶
/collection?_sort=-last_modified,field
Note
Ordering on a boolean field gives true
values first.
Note
Will return an error if a field is unknown.
Counting¶
In order to count the number of records, for a specific field value for example,
without fetching the actual collection, a HEAD
request can be
used. The Total-Records
response header will then provide the
total number of records.
See batch endpoint to count several collections in one request.
Polling for changes¶
The _since
parameter is provided as an alias for gt_last_modified
.
/collection?_since=1437035923844
When filtering on last_modified
every deleted records will appear in the
list with a deleted
flag and a last_modified
value that corresponds
to the deletion event.
If the request header If-None-Match
is provided as described in
the section about timestamps and if the
collection was not changed, a 304 Not Modified
response is returned.
Note
The _before
parameter is also available, and is an alias for
lt_last_modified
(strictly inferior).
Note
_since
and _before
also accept a value between quotes ("
) as
it would be returned in the ETag
response header
(see response timestamps).
-
Changed in version 2.4:::
_to
was renamed_before
and is now deprecated.- It will be supported until the next major version of Cliquet.
Request:
GET /articles?_since=1437035923844 HTTP/1.1
Accept: application/json
Authorization: Basic bWF0Og==
Host: localhost:8000
Response:
HTTP/1.1 200 OK
Access-Control-Allow-Origin: *
Access-Control-Expose-Headers: Backoff, Retry-After, Alert, Content-Length, ETag, Next-Page, Total-Records, Last-Modified
Content-Length: 436
Content-Type: application/json; charset=UTF-8
Date: Tue, 28 Apr 2015 12:08:11 GMT
Last-Modified: Mon, 12 Apr 2015 11:12:07 GMT
ETag: "1430222877724"
Total-Records: 2
{
"data": [
{
"id": "dc86afa9-a839-4ce1-ae02-3d538b75496f",
"last_modified": 1430222877724,
"title": "MoCo",
"url": "https://mozilla.com",
},
{
"id": "23160c47-27a5-41f6-9164-21d46141804d",
"last_modified": 1430140411480,
"title": "MoFo",
"url": "https://mozilla.org",
},
{
"id": "11130c47-37a5-41f6-9112-32d46141804f",
"deleted": true,
"last_modified": 1430140411480
}
]
}
Paginate¶
If the _limit
parameter is provided, the number of records returned is limited.
If there are more records for this collection than the limit, the
response will provide a Next-Page
header with the URL for the
Next-Page.
When there is no more Next-Page
response header, there is nothing
more to fetch.
Pagination works with sorting, filtering and polling.
Note
The Next-Page
URL will contain a continuation token (_token
).
It is recommended to add precondition headers (If-Match
or
If-None-Match
), in order to detect changes on collection while
iterating through the pages.
Partial response¶
If the _fields
parameter is provided, only the fields specified are returned.
Fields are separated with a comma.
This is vital in mobile contexts where bandwidth usage must be optimized.
Nested objects fields are specified using dots (e.g. address.street
).
Note
The id
and last_modified
fields are always returned.
Request:
GET /articles?_fields=title,url
Accept: application/json
Authorization: Basic bWF0Og==
Host: localhost:8000
Response:
HTTP/1.1 200 OK
Access-Control-Allow-Origin: *
Access-Control-Expose-Headers: Backoff, Retry-After, Alert, Content-Length, ETag, Next-Page, Total-Records, Last-Modified
Content-Length: 436
Content-Type: application/json; charset=UTF-8
Date: Tue, 28 Apr 2015 12:08:11 GMT
Last-Modified: Mon, 12 Apr 2015 11:12:07 GMT
ETag: "1430222877724"
Total-Records: 2
{
"data": [
{
"id": "dc86afa9-a839-4ce1-ae02-3d538b75496f",
"last_modified": 1430222877724,
"title": "MoCo",
"url": "https://mozilla.com",
},
{
"id": "23160c47-27a5-41f6-9164-21d46141804d",
"last_modified": 1430140411480,
"title": "MoFo",
"url": "https://mozilla.org",
}
]
}
List of available URL parameters¶
<prefix?><attribute name>
: filter by value(s)_since
,_before
: polling changes_sort
: order list_limit
: pagination max size_token
: pagination token_fields
: filter the fields of the records
Filtering, sorting, partial responses and paginating can all be combined together.
/collection?_sort=-last_modified&_limit=100&_fields=title
HTTP Status Codes¶
200 OK
: The request was processed304 Not Modified
: Collection did not change since value inIf-None-Match
header400 Bad Request
: The request querystring is invalid406 Not Acceptable
: The client doesn’t accept supported responses Content-Type.412 Precondition Failed
: Collection changed since value inIf-Match
header
POST /{collection}¶
Requires authentication
Used to create a record in the collection. The POST body is a JSON mapping containing:
data
: the values of the resource schema fields;permissions
: optional a json dict containing the permissions for the record to be created.
The POST response body is a JSON mapping containing:
data
: the newly created record, if all posted values are valid;permissions
: optional a json dict containing the permissions for the requested resource.
If the request header If-Match
is provided, and if the record has
changed meanwhile, a 412 Precondition failed
error is returned.
Request:
POST /articles HTTP/1.1
Accept: application/json
Authorization: Basic bWF0Og==
Content-Type: application/json; charset=utf-8
Host: localhost:8000
{
"data": {
"title": "Wikipedia FR",
"url": "http://fr.wikipedia.org"
}
}
Response:
HTTP/1.1 201 Created
Access-Control-Allow-Origin: *
Access-Control-Expose-Headers: Backoff, Retry-After, Alert, Content-Length
Content-Length: 422
Content-Type: application/json; charset=UTF-8
Date: Tue, 28 Apr 2015 12:35:02 GMT
{
"data": {
"id": "cd30c031-c208-4fb9-ad65-1582d2a7ad5e",
"last_modified": 1430224502529,
"title": "Wikipedia FR",
"url": "http://fr.wikipedia.org"
}
}
Validation¶
If the posted values are invalid (e.g. field value is not an integer)
an error response is returned with status 400
.
Conflicts¶
Since some fields can be defined as unique per collection, some conflicts may appear when creating records.
Note
Empty values are not taken into account for field unicity.
Note
Deleted records are not taken into account for field unicity.
If a conflict occurs, an error response is returned with status 409
.
A details
attribute in the response provides the offending record and
field name. See dedicated section about errors.
Timestamp¶
When a record is created, the timestamp of the collection is incremented.
It is possible to force the timestamp if the specified record has a
last_modified
attribute.
If the specified timestamp is in the past, the collection timestamp does not take the value of the created record but is bumped into the future as usual.
HTTP Status Codes¶
201 Created
: The record was created400 Bad Request
: The request body is invalid406 Not Acceptable
: The client doesn’t accept supported responses Content-Type.409 Conflict
: Unicity constraint on fields is violated412 Precondition Failed
: Collection changed since value inIf-Match
header415 Unsupported Media Type
: The client request was not sent with a correct Content-Type.
New in version 2.13::: Enforcement of the timestamp value for records has been added.
DELETE /{collection}¶
Requires authentication
Delete multiple records. Disabled by default, see Configuration.
The DELETE response is a JSON mapping containing:
data
: list of records that were deleted, without schema fields.
It supports the same filtering capabilities as GET.
If the request header If-Match
is provided, and if the collection
has changed meanwhile, a 412 Precondition failed
error is returned.
Request:
DELETE /articles HTTP/1.1
Accept: application/json
Authorization: Basic bWF0Og==
Host: localhost:8000
Response:
HTTP/1.1 200 OK
Access-Control-Allow-Origin: *
Access-Control-Expose-Headers: Backoff, Retry-After, Alert, Content-Length
Content-Length: 193
Content-Type: application/json; charset=UTF-8
Date: Tue, 28 Apr 2015 12:38:36 GMT
{
"data": [
{
"deleted": true,
"id": "cd30c031-c208-4fb9-ad65-1582d2a7ad5e",
"last_modified": 1430224716097
},
{
"deleted": true,
"id": "dc86afa9-a839-4ce1-ae02-3d538b75496f",
"last_modified": 1430224716098
}
]
}
HTTP Status Codes¶
200 OK
: The records were deleted;405 Method Not Allowed
: This endpoint is not available;406 Not Acceptable
: The client doesn’t accept supported responses Content-Type.412 Precondition Failed
: Collection changed since value inIf-Match
header
GET /{collection}/<id>¶
Requires authentication
Returns a specific record by its id. The GET response body is a JSON mapping containing:
data
: the record with exhaustive schema fields;permissions
: optional a json dict containing the permissions for the requested record.
If the request header If-None-Match
is provided, and if the record has not
changed meanwhile, a 304 Not Modified
is returned.
Request:
GET /articles/d10405bf-8161-46a1-ac93-a1893d160e62 HTTP/1.1
Accept: application/json
Authorization: Basic bWF0Og==
Host: localhost:8000
Response:
HTTP/1.1 200 OK
Access-Control-Allow-Origin: *
Access-Control-Expose-Headers: Backoff, Retry-After, Alert, Content-Length, ETag, Last-Modified
Content-Length: 438
Content-Type: application/json; charset=UTF-8
Date: Tue, 28 Apr 2015 12:42:42 GMT
ETag: "1430224945242"
{
"data": {
"id": "d10405bf-8161-46a1-ac93-a1893d160e62",
"last_modified": 1430224945242,
"title": "No backend",
"url": "http://nobackend.org"
}
}
HTTP Status Code¶
200 OK
: The request was processed304 Not Modified
: Record did not change since value inIf-None-Match
header406 Not Acceptable
: The client doesn’t accept supported responses Content-Type.412 Precondition Failed
: Record changed since value inIf-Match
header
DELETE /{collection}/<id>¶
Requires authentication
Delete a specific record by its id.
The DELETE response is the record that was deleted. The DELETE response is a JSON mapping containing:
data
: the record that was deleted, without schema fields.
If the record is missing (or already deleted), a 404 Not Found
is returned.
The consumer might decide to ignore it.
If the request header If-Match
is provided, and if the record has
changed meanwhile, a 412 Precondition failed
error is returned.
Note
Once deleted, a record will appear in the collection when polling for changes,
with a deleted status (delete=true
) and will have most of its fields empty.
Timestamp¶
When a record is deleted, the timestamp of the collection is incremented.
It is possible to force the timestamp by passing it in the
querystring with ?last_modified=<value>
.
If the specified timestamp is in the past, the collection timestamp does not take the value of the deleted record but is bumped into the future as usual.
HTTP Status Code¶
200 OK
: The record was deleted406 Not Acceptable
: The client doesn’t accept supported responses Content-Type.412 Precondition Failed
: Record changed since value inIf-Match
header
New in version 2.13::: Enforcement of the timestamp value for records has been added.
PUT /{collection}/<id>¶
Requires authentication
Create or replace a record with its id. The PUT body is a JSON mapping containing:
data
: the values of the resource schema fields;permissions
: optional a json dict containing the permissions for the record to be created/replaced.
The PUT response body is a JSON mapping containing:
data
: the newly created/updated record, if all posted values are valid;permissions
: optional the newly created permissions dict, containing the permissions for the created record.
Validation and conflicts behaviour is similar to creating records (POST
).
If the request header If-Match
is provided, and if the record has
changed meanwhile, a 412 Precondition failed
error is returned.
Request:
PUT /articles/d10405bf-8161-46a1-ac93-a1893d160e62 HTTP/1.1
Accept: application/json
Authorization: Basic bWF0Og==
Content-Type: application/json; charset=utf-8
Host: localhost:8000
{
"data": {
"title": "Static apps",
"url": "http://www.staticapps.org"
}
}
Response:
HTTP/1.1 200 OK
Access-Control-Allow-Origin: *
Access-Control-Expose-Headers: Backoff, Retry-After, Alert, Content-Length
Content-Length: 439
Content-Type: application/json; charset=UTF-8
Date: Tue, 28 Apr 2015 12:46:36 GMT
ETag: "1430225196396"
{
"data": {
"id": "d10405bf-8161-46a1-ac93-a1893d160e62",
"last_modified": 1430225196396,
"title": "Static apps",
"url": "http://www.staticapps.org"
}
}
Timestamp¶
When a record is created or replaced, the timestamp of the collection is incremented.
It is possible to force the timestamp if the specified record has a
last_modified
attribute.
For replace, if the specified timestamp is less or equal than the existing record, the value is simply ignored and the timestamp is bumped into the future as usual.
For creation, if the specified timestamp is in the past, the collection timestamp does not take the value of the created/updated record but is bumped into the future as usual.
HTTP Status Code¶
201 Created
: The record was created200 OK
: The record was replaced400 Bad Request
: The record is invalid406 Not Acceptable
: The client doesn’t accept supported responses Content-Type.409 Conflict
: If replacing this record violates a field unicity constraint412 Precondition Failed
: Record was changed or deleted since value inIf-Match
header.415 Unsupported Media Type
: The client request was not sent with a correct Content-Type.
Note
A If-None-Match: *
request header can be used to make sure the PUT
won’t overwrite any record.
New in version 2.13::: Enforcement of the timestamp value for records has been added.
PATCH /{collection}/<id>¶
Requires authentication
Modify a specific record by its id. The PATCH body is a JSON mapping containing:
data
: a subset of the resource schema fields (key-value replace);permissions
: optional a json dict containing the permissions for the record to be modified.
The PATCH response body is a JSON mapping containing:
data
: the modified record (full by default);permissions
: optional the modified permissions dict, containing the permissions for the modified record.
If a request header Response-Behavior
is set to light
,
only the fields whose value was changed are returned. If set to
diff
, only the fields whose value became different than
the one provided are returned.
Request:
PATCH /articles/d10405bf-8161-46a1-ac93-a1893d160e62 HTTP/1.1
Accept: application/json
Authorization: Basic bWF0Og==
Content-Type: application/json; charset=utf-8
Host: localhost:8000
{
"data": {
"title": "No Backend"
}
}
Response:
HTTP/1.1 200 OK
Access-Control-Allow-Origin: *
Access-Control-Expose-Headers: Backoff, Retry-After, Alert, Content-Length
Content-Length: 439
Content-Type: application/json; charset=UTF-8
Date: Tue, 28 Apr 2015 12:46:36 GMT
ETag: "1430225196396"
{
"data": {
"id": "d10405bf-8161-46a1-ac93-a1893d160e62",
"last_modified": 1430225196396,
"title": "No Backend",
"url": "http://nobackend.org"
}
}
If the record is missing (or already deleted), a 404 Not Found
error is returned.
The consumer might decide to ignore it.
If the request header If-Match
is provided, and if the record has
changed meanwhile, a 412 Precondition failed
error is returned.
Note
last_modified
is updated to the current server timestamp, only if a
field value was changed.
Note
JSON-Patch is currently not supported. Any help is welcomed though!
Read-only fields¶
If a read-only field is modified, a 400 Bad request
error is returned.
Conflicts¶
If changing a record field violates a field unicity constraint, a
409 Conflict
error response is returned (see error channel).
Timestamp¶
When a record is modified, the timestamp of the collection is incremented.
It is possible to force the timestamp if the specified record has a
last_modified
attribute.
If the specified timestamp is less or equal than the existing record, the value is simply ignored and the timestamp is bumped into the future as usual.
HTTP Status Code¶
200 OK
: The record was modified400 Bad Request
: The request body is invalid, or a read-only field was modified406 Not Acceptable
: The client doesn’t accept supported responses Content-Type.409 Conflict
: If modifying this record violates a field unicity constraint412 Precondition Failed
: Record changed since value inIf-Match
header415 Unsupported Media Type
: The client request was not sent with a correct Content-Type.
New in version 2.13::: Enforcement of the timestamp value for records has been added.
Notes on permissions attribute¶
Shareable resources allow permissions management via the permissions
attribute
in the JSON payloads, along the data
attribute. Permissions can be replaced
or modified independently from data.
On a request, permissions
is a JSON dict with the following structure:
"permissions": {<permission>: [<list_of_principals>]}
Where <permission>
is the permission name (e.g. read
, write
)
and <list_of_principals>
should be replaced by an actual list of
principals.
Example:
{
"data": {
"title": "No Backend"
},
"permissions": {
"write": ["twitter:leplatrem", "group:ldap:42"],
"read": ["system.Authenticated"]
}
}
In a response, permissions
contains the current permissions of the record
(i.e. the modified version in case of a creation/modification).
Note
When a record is created or modified, the current :term`user id`
is always added among the write
principals.
Read more about leveraging resource permissions <resource-permissions>.
Changed in version 2.6::: With a PATCH
request, the list of principals for the specified permissions
is now replaced by the one provided.