REST API

For REST API reference documentation please choose (?)/Web API from the portal or visit /relution/portal/#/web-api directly. OpenAPI v3 (Swagger) metadata is served at /openapi.json suitable for consumption by OpenAPI v3 codegen. Prebuild clients for Java and TypeScript are available upon request.

In particular the following requests are relevant for IoT middleware development:

  • site: /relution/api/v1/sites

  • devices: /relution/api/v1/devices

  • geofences: /relution/api/v1/iot/geofences

  • environment profiles: /relution/api/v1/iot/sites/{siteUuid}/environmentProfiles/{profileType}

  • asset tracking history: /relution/api/v1/iot/indoor/positionEstimates

Querying

Portal UIs often require sorting, filtering and paging which are commonly supported by most GET resources requests in the form of query parameters.

For example, the following request queries the 10 last recently updated, non-deleted devices:

/relution/api/v1/devices?limit=10&offset=0&sortOrder=-modificationDate%2C%2Buuid&filter=%7B%22type%22%3A%22logOp%22%2C%22operation%22%3A%22NOT%22%2C%22filters%22%3A%5B%7B%22type%22%3A%22stringEnum%22%2C%22fieldName%22%3A%22status%22%2C%22values%22%3A%5B%22DELETED%22%5D%7D%5D%7D&getItems=true&getNonpagedCount=true

using these query parameter options:

  • limit=10 to retrieve a maximum of 10 devices only,

  • offset=0 to retrieve the first devices (used for pagination),

  • getItems=true to actually fetch device data,

  • getNonpagedCount=true to also fetch the total number of items disregarding limit and offset,

  • sortOrder=-modificationDate,+uuid: to sort by modificationDate descending latest to oldest followed by uuid primary key ascending ensuring total order,

  • filter={ "type": "logOp", "operation": "NOT", "filters": [{ "type": "stringEnum", "fieldName": "status", "values": ["DELETED"]}]} meaning status <> 'DELETED'.

Please see below for detailed description of these query parameters.

Sorting

To sort on attributes set accessor paths as sortOrder query parameter. An accessor path is a simple JavaScript-style expression using a dot-notation for accessing attributes. To sort ascending or descending prefix the accessor path by + or -, respectively. Ascending order is the default if neither + nor - is given. Comparisons are performed in order of accessors given.

For example +time,-accuracy,uuid sorts ascending by time, descending by accuracy when times are equal and ascending by uuid when both times and accuracies are equal.

Notice, to get deterministic results it is important to set up a total order. This means the order comparison is defined such that no two distinct attribute sets are considered equal. The safest way of ensuring this is by specifying a key attribute as last resort, like the uuid above.

Filtering

Filtering of data is enabled by setting the filter query parameter to a JSON encoded for URLs. The filter is given as a JSON object tree, typically coded as a literal. Simple Filters operate on individual fields selected by an accessor path as described above. A number of these field filters can then be combined using boolean algebra forming more complex Composite Filters.

The filter constructions allow representing most WHERE clauses of SQL and are mapped efficiently to in-memory filtering, SQL databases, MongoDB, etc.

Simple Filters

Given a model having a surName attribute of string type, one can select all records having a surName starting with the letter M using a simple like filter literal:

{
	"type": "like",
	"fieldName": "surName",
	"like": "M%"
}

Assuming an integral age attribute is present, selecting records of age 20 to 30 is formulated using a long range filter:

{
	"type": "longRange",
	"fieldName": "age",
	"min": 20
	"max": 30
}

The table lists all simple filters available. All of these filters require to set the type attribute to the given value and an accessor path as fieldName. Additional attributes to be set are given in the table:

Type Attributes Description

boolean

value

matches given boolean value.

containsString

contains

text containing the given string.

dateRange

min/max

dates between optional min/max inclusive.

doubleRange

min/max

floating point values between optional min/max inclusive.

like

like

text satisfying a like expression, % serving as wildcard.

longEnum

values

number in a given set of values.

longRange

min/max

numbers values between optional min/max inclusive.

stringEnum

values

text in a given set of values.

string

value

matches a given textual value.

stringMap

key/value

dictionary must contains key of given value.

stringRange

min/max

text values between optional min/max inclusive.

null

isNull

tests presence of an attribute value.

Notice, min/max of range filters are optional allowing for greater-than and less-than matches by omitting the upper or lower bound value, respectively.

Composite Filters

The two example filters above can be combined to select records with surName starting with M and age between 20 and 30:

{
	"type": "logOp",
	"operation": "and",
	"filters": [
		{
			"type": "like",
			"fieldName": "surName",
			"like": "M%"
		}, {
			"type": "longRange",
			"fieldName": 'age',
			"min": 20,
			"max": 30
		}
	]
}

The logical operations defined so far are given in the following table:

Operation Description

and

logical AND, all aggregated filters must be matched.

or

logical OR, any aggregated filter must be matched.

nand

logical NAND, matches if any aggregated filter is not matched.

nor

logical NOR, does not match if aggregated any filter is matched.

Logical negation is available using not and specifying a single aggregated filter:

{
	"type": "logOp",
	"operation": "not",
	"filters": [
		"type": "string',
		"fieldName": "surName",
		"value": "Meyer"
	]
}

Paging

For paging limit and/or offset query parameters are supported.

The offset parameter extracts records from the given index on. The limit parameter extracts up to the given number of records. The nonPagedCount result operates on the filtered range of records. Notice, to get predictable and repeatable results a sortOrder is required imposing a total order of records, see: Sorting above.