|
DLI REST-style API Reference
|
The WebDAV RFC [6], where HTTP 207 Multiple responses code is defined, is XML-centric, and requires that the response type be XML. The API generates this code when processing matrix URI requests, and produces output in the format requested by the client in the Accept header instead, because we believe it to be more useful. However, the spirit of the RFC is preserved as much as possible so as not to introduce complexity.
The HTML-formatted response follows the format defined in [6], but instead of custom elements, it creates div elements with corresponding classes.
The JSON-formatted response contains an array of responses. The HTTP response will contain corresponding "Link: <...>, rel=item" headers which can be used to gain the information on what resource each response is returned from.
PUT is normally an idempotent method, but it may interact with matrix URIs in a possibly unexpected manner. For example, consider
PUT /restapi/auth/users/name=fred/name/ HTTP/1.0 ... value=joe
This request will rename user 'fred' to 'joe'. It is all fine and the request will work as expected. However, it won't technically be idempotent because /restapi/auth/users/name=fred/ will no longer resolve (Fred is now Joe). This would also happen if you used PATCH, but PATCH isn't expected to be idempotent, while PUT is.
Referring to that user by their sequential number would make the request idempotent:
PUT /restapi/auth/users/2/name/ HTTP/1.0 ... value=joe
Such a request would be idempotent.
Due to the JSON representation of data and expressing manipulations with it using JSON patch, it's not possible for a request like
DELETE /restapi/auth/users/2/ HTTP/1.0
to be idempotent: deleting a value from a JSON array causes reindexing of successive elements, so user #3 becomes user #2, user #4 becomes user #3, etc. You should not rely on DELETE to be idempotent in this case. We have no concept of 'identity' for parameters stored in JSON arrays.
A better way to delete a user could be by name, e.g.
DELETE /restapi/auth/users/name=fred/ HTTP/1.0
Such a request would be idempotent (it would still have the reindexing side effect though).
If you really want to change properties of objects by which you selected them in a matrix URI, or delete objects by their sequential number, and want to notify any intermediaries that the request is not actually idempotent, you should wrap them in POST requests using HTTP verb tunneling.
All function calls are performed by POST requests to the function's URI. However, some of these functions, like getting a history of a meter's values over a period of time, are semantically nilpotent (have no side effects), so GET could be used. Unfortunately, most of these functions have arguments, which are to be sent in the request body for content type detection to be meaningful, and sending a body in a GET request is not standard. So, POST is used instead.
We allow PATCH to operate on resources which are read-only by nature, or writes to which are denied by policy. The reason for this is that a patch doesn't have to contain modifying operations, just test operations, and may even not contain any operations at all, in which case such resources are valid PATCH targets.
The JSON patch "move" and "replace" operations are specified [4] to be functionally identical to a "remove" operation, followed by an "add" operation. There are obvious problems when attempting to apply such principles to additionally constrained objects with internal behaviour.
Some objects (e.g. the administrative user) can not be subjected to a "remove" operation, and attempting to move them e.g. for simple reordering may fail. Additionally, such operations will erase any internal state of the removed object, so e.g. you can safely move or replace only a disabled AutoPing entry.
Additionally, heterogeneous containers cannot have their fields removed, so such "replace" behaviour would be useless for the fields.
Strict adherence to principles of REST would require all possible links to be exposed to the client, but it's simply not feasible to enumerate all use cases for matrix URIs. Technically we could give you so-called opaque URIs for all resources from the entry point, like:
We could document the link relations, content subtypes and all that, and become more HATEOAS compliant, but this doesn't seem practical. Rather, we choose to make URI structure represent the data model, and rely on you to apply common sense and patterns discussed in this reference to the information you obtain from the API to generate URIs.
In case some part of the URI scheme changes, we expect to be able to emulate existing resource links, or redirect you from old locations using standard HTTP 30x Redirect responses, so you will at least be notified that the URI scheme has changed (correctly configured clients would understand the redirect). Resources that were once present but have been discontinued would yield 410 Gone HTTP responses.