DLI REST-style API Reference
20210120T184950Z
Overview

REST is an architectural style where data are presented and manipulated as an hierarchy of resources, and the underlying communications protocol (commonly HTTP) is used to perform action signaling, content negotiation, etc [11]. In practice this means automated clients for it are easier to implement; they can send and receive state in different formats (representations of resources). The REST-style API follows the principles of REST principles where possible without sacrificing simplicity or adding unnecessary bloat.

Target audience

The REST-style API is designed to be used for automating access to the device, but can also be used manually with the browser. Due to the way device configuration is implemented, any new configuration variables are exposed to the REST API automatically, while designing would take time.

Design goals

  • Simple uniform widely-implemented interfaces

    The REST-style API identifies resources with URIs [1]. Just about everything there is to know about the controller (states of the outlets and their names, different environment meters, AutoPing items, network interfaces and authorized users, etc.) has its place in an hierarchical URI namespace. Groups of similar resources (e.g. all locked outlets, or all voltage meters, or all enabled AutoPing items) have matrix URIs (see later) to reference them as a group.

    The API relies on HTTP, a widely implemented protocol, to perform:

    • action signaling (what to do with the specified resource);
    • content negotiation (what format you want to input data in and how you want to receive output);
    • limiting output verbosity or nesting (only get the data you need);
    • related resource discovery (with the Link headers).
  • Feature compatibility with existing web UI and legacy API

    If you are reading this, you have probably used some scripts to access the DLI power controllers. It wasn't convenient, sometimes involved reverse engineering the web pages output by the devices, etc. But it allowed you to automate a lot of device configuration and control tasks. The REST-style API intends to allow access to the same, and more parameters, in a uniform fashion. The legacy APIs will remain in place, but now there's an alternative.

  • Discoverability

    You can use your web browser to access the API, to discover the visible configuration and state resources, and manipulate them. That's actually what the web UI advises you to do.

    Discovering the API without a browser is also possible, just less convenient. For example, you can get a representation of the whole configuration by issuing a GET request to the API root (/restapi/) requesting output as JSON (Accept: application/json). However, without extra information it's not obvious what further actions you can take, and HTML output explains most of it to you (and provides forms for you).

  • Extensibility

    The way the API is designed makes it easier for us to integrate new features into the controllers, and for you to find them. For example, if you have a script to cycle all outlets, it will really cycle them all, even if the controller has more outlets than you expected.

  • Ease of use for common operations

    The underlying data model and primary interchange format are based on JSON, a compact widely supported notation [3]. For example, you can switch off all non-locked outlets, or retrieve the states of all outlets at once, with a single request (in the latter case you will just receive an array of states if you need, you won't have to parse HTML), and that without sacrificing the uniformity.

  • Flexibility

    Requests with different HTTP headers will may accept different argument types and yield different representations of resources (e.g. plain text, HTML, JSON, etc.). If you are interested in a yet unsupported encoding, please let us know and we'll happily add it, without sacrificing compatibility.

  • Consistency

    Different means of achieving seemingly same results should be as equivalent as possible. For example, you could change a property of an object by issuing a PUT request to that property, or by issuing an appropriate PATCH request to parent (object's) URL, and the behavior should be the same; same goes for DELETE.