Skip to content
This repository has been archived by the owner on Oct 12, 2023. It is now read-only.

API guidelines

Devis Lucato edited this page Jun 27, 2017 · 7 revisions
  • When sending an object always use JSON and include a header Content-Type: application/json; charset=utf-8
  • Collection names in the URL are in plural form, e.g. "devices", "groups"
  • Timestamped lists are sorted by time, ascending or descending, using the order query parameter.
  • API calls always return entire objects (bandwidth optimization is not in the current scope).
  • Every object has a $metadata property with links, schema and versioning details.
  • When an API returns a list, the list is paginated, with maximum 10000 items per page.
  • All API endpoints are versioned. Currently all API endpoints use a /v1/ path prefix.

Creating a resource

Resources can be created in two ways:

  1. POST {endpoint}/{collection name}
  2. PUT {endpoint}/{collection name}/{resource ID}

In the first case, the ID is automatically generated. Both requests return the the full object created in the response.

Updating a resource

Resources can be updated in two ways:

  1. PUT {endpoint}/{collection name}/{resource ID}
  2. PATCH {endpoint}/{collection name}/{resource ID}

Both requests pass the resource ETag to manage optimistic concurrency.

PATCH is not always implemented, we currently use PATCH only to start/stop simulations.

Fetching a resource

GET {endpoint}/{collection name}/{resource ID}

The response is the same returned by resource creation and update.

Fetching a list

Lists can be fetched in two ways. The first is the preferred method, and should be used when the query parameters fit in the URL. The second method is used when the URL would be too long otherwise (which would result in HTTP Error 414).

  1. GET {endpoint}/{collection name}?{query options}
  2. POST {endpoint}/{collection name}-query (note the "-query" suffix)
    {
        Query: {
            query options
        }
    }
    

When a list is retrieved with pagination, and the list has a "next page", the $metadata object in the response contains a link to the next page (without the device IDs though). If the list needs to be retrieved with POST because the URI would be too long, the UI is responsible to prepare the payload with the right query options (i.e. the right combination of limit and skip).

Common query parameters

The following parameters are implemented only when there is a use case, otherwise they are ignored. Key and values are not case sensitive, though query parameters should be lowercased, and payload keys should be camel-cased.

  • from={time}: starting point of a time based list
  • to={time}: end point of a time based list
  • limit={count}: maximum number of items to return
  • grouplimit={count}: used when returning items grouped by device, to limit the number of items for each device (e.g. "retrieve last 10 alerts for device A, B and C" returns up to 30 alerts)
  • sampling={ISO 8601 duration}: used to reduce the number of items returned in a time based list (e.g. "PT5M" => "return 1 record for each 5 minute period")
  • skip={count}: items to skip from the top, used for pagination
  • order={asc|desc}: used for timestamped record lists. "asc" is the default order.
  • totalcount={Y|N}: whether to calculate the total number of items
    • Use this option with caution, because of the extra consumption cost, and the extra latency incurred
    • Don't use the TotalCount option to calculate the number of pages, just repeat until there is no "next page" link
    • Due to implementation details and scalability factors, the count might be approximated

Sampling

Sampling is used when retrieving telemetry for long periods, in cases where a normal result could contain thousands or hundreds of thousands of records. When sampling, the backend web service returns only a subset of the actual records.

When sampling a list, the backend service does not calculate average values. Sampling is used only to pass through a manageable amount of records, when a UI graph is showing data for long periods like weeks, months, etc.

Consider for example a scenario where a device sends one message per second, and every message contains four values (e.g. temperature, humidity, speed, geolocation). In this scenario the device is sending 3600 messages per hour, with dynamic values. When asking for this device telemetry, requesting a sampling of 1 hour, the API will return the latest value of each hour.

Timestamp values

When passing a timestamp, values are always interpreted as UTC values. Future values are allowed.

The following formats are supported:

  • yyyy-mm-ddThh:mm:ss.mmm, e.g. 2017-07-19T16:45:48.123, equivalent to 2017-07-19T16:45:48.123Z
  • yyyy-mm-ddThh:mm:ss, e.g. 2017-07-19T16:45:48, equivalent to 2017-07-19T16:45:48.000Z
  • yyyy-mm-ddThh:mm, e.g. 2017-07-19T16:45, equivalent to 2017-07-19T16:45:00.000Z
  • yyyy-mm-ddThh, e.g. 2017-07-19T16, equivalent to 2017-07-19T16:00:00.000Z
  • yyyy-mm-dd, e.g. 2017-07-19, equivalent to 2017-07-19T00:00:00.000Z
  • yyyy-mm, e.g. 2017-07, equivalent to 2017-07-01T00:00:00.000Z
  • yyyy, e.g. 2017, equivalent to 2017-01-01T00:00:00.000Z
  • NOW
  • NOW-{ISO 8601 duration}, e.g. NOW-PT5M. For example a client can request telemetry using "?from=NOW-PT5M&to=NOW".