Resource Query Language (RQL)

RQL, or Resource Query Language, is a query language used for querying and manipulating resources through the URI. RQL provides the ability to filter, sort, paginate, and project data. It is straightforward to use, yet it offers flexibility to address complex scenarios.

For applications written in JavaScript or TypeScript, we highly recommend using our SDK to build RQL queries.

Using RQL

RQL is composed of a set of operators. These operators can be broadly classified into three categories:

  • Comparison Operators: These operators perform comparison operators, such as equals, greater than, etc.

  • Logical Operators: Used to combine multiple conditions

  • Algorithmic Operators: These operators pertain to functionalities like sorting and pagination.

Operators are represented in the format operator(arg1,arg2,...). Everything can be expressed as a set of such operators by means of nesting .

Practical Examples

Lets say you want to host a web page that features a table listing all users of a specific medical device application. Implementing filtering is crucial. This is where RQL enter the picture.

Try It Yourself

You can test the following examples in real-time by going to Extra Horizon's Control Center. Our Control Center offers a user table for your medical device application that supports RQL queries.


Basic Filtering

To display users with the first name "Adam" in the table, your GET request would look like:

GET /users/v1/?eq(first_name,Adam)

Sorting

To sort users based on their creation timestamp:

GET /users/v1/?sort(creation_timestamp)

Pagination

To paginate your results with a limit of 10 users and to retrieve the third page:

GET /users/v1/?limit(10,20)
  • First parameter 10 expresses the number of users to return

  • Second parameter 20 offsets the starting position in the result set. The first 20 users will be skipped.

Projection

To request only specific fields such as first_name, last_name, and creation_timestamp:

GET /users/v1/?select(first_name,last_name,creation_timestamp)

Combining Operators

Logical operators can be used to combine multiple operators. For example, to filter users with first name "Adam" and last name "Smith":

GET /users/v1/?and(eq(first_name,Adam),eq(last_name,Smith))

Algorithmic operators can be added in the same fashion:

GET /users/v1/?and(eq(first_name,Adam),select(first_name))

Operators

Advanced use cases

Filtering by array length

To filter a field of type array by it's length, for example the following syntax will return users with 0 - 5 roles assigned to them.

GET /users/v1/?excludes(roles.5)

Limitations

Every tool has its constraints, and RQL is no exception. Understanding these limitations helps you use RQL more effectively.

Casting values

RQL automatically tries to guess the type of the values you provide. Most of the time this works well, but not always. For instance, searching for a number which is stored as a string can cause issues.

For example, the user service can store phone numbers and these are stored as strings. When searching for a specific phone number you'll have to tell RQL your looking for a string value. The following query won't work:

GET /users/v1/?eq(phone_number,12345678)

You'll have to tell RQL you're searching for a string by "casting" your value with a string: prefix:

GET /users/v1/?eq(phone_number,string:12345678)

The same happens for values which look like dates. For instance, querying like this for a birthday in the profile service like this won't work:

GET /profiles/v1/?eq(birthday,1970-01-01)

The value also needs to be prefixed by the string: casting mechanism:

GET /profiles/v1/?eq(birthday,string:1970-01-01)

Double Encoding of Special Characters

Imagine a scenario where you need to filter records based on a description that includes the string a)a:

GET /data/v1/?like(description,a)a)

Executing the above query without any modifications results in an INVALID_RQL_EXCEPTION. The problem lies with the special character ). RQL can't discern whether the ) marks the end of the argument list or is part of the string value a)a.

You might think of solving this by URL encoding the special character ) as %29:

GET /data/v1/?like(description,a%29a)

Unfortunately, this approach still triggers an INVALID_RQL_EXCEPTION. The reason lies in RQL's automatic decoding of incoming requests, a design choice to accommodate HTTP clients that perform automatic URL encoding. Consequently the encoded %29 gets decoded back to ), leaving us with the initial problem.

To effectively handle special characters, RQL mandates double encoding for such string values. This means that the special character should be encoded twice. Here's how you would apply double encoding to the initial query:

GET /data/v1/?like(description,a%2529a)

It is highly recommended to use our SDK if you are building a JavaScript or Typescript application. Our SDK will automatically double encode string values.

Double encoding is not limited to parentheses. RQL requires all special characters to be double encoded:

  • Simple symbols like /, (, ], ".

  • Accents such as é, à, ö.

  • Whitespace characters including spaces, newlines, and tabs.

Services with the skip count RQL operator

The skip count RQL operator is currently supported in select services, and efforts are underway to make it available for all services in the near future. Attempting to use the skip count on a service that does not yet support it may result in an INVALID_RQL_EXCEPTION.

Services currently supporting the skip count operator:

  • Data Service

  • Events Service

  • Profiles Service

  • Tasks Service

  • Users Service

  • Notification Service

Last updated