Core - RESTful API Support

The framework allows the creation of RESTful web API for a Service that enables access to ecosystem’s resources and data.

Call a REST API method

To read from or write to a resource such as a user or an email message, you construct a request that looks like the following:

{HTTP-method} https://{public-url}/api/{service}/{version}/{resource}?{query-parameters}

The components of a request include:

  • {HTTP-method}: The HTTP method used on the request to the endpoint.
  • {public-url}: The external URL use to reach WebTop installation.
  • {service}: The service ID.
  • {version}: The version of API provided by the Service.
  • {resource}: The resource exposed by the Service that you’re referencing.
  • {query-parameters}: Optional query options or REST method parameters that customize the response.

After you make a request, a response is returned that includes:

  • Status code: An HTTP status code that indicates success or failure. For details about HTTP error codes, see Errors.
  • Response message: The data that you requested or the result of the operation. The response message can be empty for some operations.

HTTP methods

Endpoints uses the HTTP method on your request to determine what your request is doing. Depending on the resource, the API may support operations including actions, functions, or CRUD operations described below.

Method Description
GET Read data from a resource.
POST Create a new resource, or perform an action.
PATCH Update a resource with new values.
PUT Replace a resource with a new one.
DELETE Remove a resource.
  • For the CRUD methods GET and DELETE, no request body is required.
  • The POST, PATCH, and PUT methods require a request body, usually specified in JSON format, that contains additional information, such as the values for fields of the resource.

Version

Services can manage versions completely autonomously. A dedicated endpoint will be created for each version defined in the spec.

Resource

A resource can be an entity or complex type, commonly defined with properties. Entities differ from complex types by always including an id property.

Your URL will include the resource you are interacting with in the request, such as me, user, group, and domain. Often, top-level resources also include relationships, which you can use to access additional resources, like me/messages or me/drive. You can also interact with resources using methods; for example me/my-method.

Each resource might require different permissions to access it. You will often need a higher level of permissions to create or update a resource than to read it.

Query parameters

Query parameters can be standardized query options, or other strings that a method accepts to customize its response.

You can use optional standardized query options to include more or fewer properties than the default response, filter the response for items that match a custom query, or provide additional parameters for a method.

Standardized query options

A Rest API operation might support one or more of the following query options.

Name Description
_filter Filters results (rows).
_orderBy Orders results.
_select Filters properties (columns).
_update Specifies the properties (columns) to update.
_pageNo The specific page to get, if set activates paging (client-side paging).
_pageSize The number of items to return for each page (client-side paging).
_return_count Specifies whether to return the total count of items.
_syncToken Specifies the token that tracks changes from a precise state (used in delta apis).
_filter parameter

Use the _filter query parameter to restrict the results of a request to match a search criterion.

It’s syntax and behavior adhere to REST API Query language, see section RSQL for more info about it’s grammar.

The expression specified with _filter is evaluated for each resource in the collection, and only items where the expression evaluates to true are included in the response. Resources for which the expression evaluates to false or to null, or which reference properties that are unavailable due to permissions, are omitted from the response.

For example, the following request returns only items whose name is equal to Kill Bill:

?_filter=name=="Kill Bill"
_orderBy parameter

Use the _orderby query parameter to specify the sort order of the items returned. The default order is ascending order.

For example, the following request returns items ordered by their display-name in ascending order:

?_orderBy=displayName

To sort the results in ascending or descending order, append either ASC or DESC to the field name, separated by a space; for example, ?$_orderBy=name DESC (unencoded), ?_orderBy=name%20DESC (URL encoded). If the sort order isn’t specified, the default ascending order is inferred.

_select parameter

Use the _select query parameter to return a subset of properties for a resource. With _select, you can specify a subset or a superset of the default properties.

The parameter needs to be specified as a comma-separated list of field names:

?_select=from,subject

Note

In general, we recommend that you use _select to limit the properties returned by a query to those needed by your app. This is especially true of queries that might potentially return a large result set. Limiting the properties returned in each row will reduce network load and help improve your app’s performance.

_pageNo parameter

Use the _pageNo query parameter to specify the exact page number to return when pagination is used. See Pagination for more info.

?_pageNo=1
_pageSize parameter

Use the _pageSize query parameter to specify how many items to return when pagination is used. See Pagination for more info.

?_pageSize=100
_returnCount parameter

Use the _returnCount query parameter to return the total count of items, useful when paginating data. See Pagination section for more info.

?_returnCount=true
_syncToken parameter

Use the _syncToken query parameter to specify in delta queries the initial state from which return changes. See Synchronization section for more info.

?_syncToken=

RSQL

RSQL is a query language for parametrized filtering of entries in RESTful APIs. It’s based on FIQL (Feed Item Query Language) – an URI-friendly syntax for expressing filters across the entries in an Atom Feed. FIQL is great for use in URI; there are no unsafe characters, so URL encoding is not required. On the other side, FIQL’s syntax is not very intuitive and URL encoding isn’t always that big deal, so RSQL also provides a friendlier syntax for logical operators and some of the comparison operators.

Grammar and semantic

RSQL expression is composed of one or more comparisons, related to each other with logical operators:

  • Logical AND : ; or and
  • Logical OR : , or or

By default, the AND operator takes precedence (i.e. it’s evaluated before any OR operators are). However, a parenthesized expression can be used to change the precedence, yielding whatever the contained expression yields.

input          = or, EOF;
or             = and, { "," , and };
and            = constraint, { ";" , constraint };
constraint     = ( group | comparison );
group          = "(", or, ")";

Comparison is composed of a selector, an operator and an argument.

comparison     = selector, comparison-op, arguments;

Selector identifies a field (or attribute, element, …) of the resource representation to filter by. It can be any non empty Unicode string that doesn’t contain reserved characters (see below) or a white space. The specific syntax of the selector is not enforced by this parser.

selector       = unreserved-str;

Comparison operators are in FIQL notation and some of them has an alternative syntax as well:

  • Equal to: ==
  • Not equal to: !=
  • Like to: =like=
  • Not like to: =nlike=
  • Less than: =lt=
  • Less than or equal to: =le=
  • Greater than operator: =gt=
  • Greater than or equal to: =ge=
  • Between: =btw=
  • Not between: =nbtw=
  • In: =in=
  • Not in: =out=

Argument can be a single value, or multiple values in parenthesis separated by comma. Value that doesn’t contain any reserved character or a white space can be unquoted, other arguments must be enclosed in single or double quotes.

arguments      = ( "(", value, { "," , value }, ")" ) | value;
value          = unreserved-str | double-quoted | single-quoted;

unreserved-str = unreserved, { unreserved }
single-quoted  = "'", { ( escaped | all-chars - ( "'" | "\" ) ) }, "'";
double-quoted  = '"', { ( escaped | all-chars - ( '"' | "\" ) ) }, '"';

reserved       = '"' | "'" | "(" | ")" | ";" | "," | "=" | "!" | "~" | "<" | ">";
unreserved     = all-chars - reserved - " ";
escaped        = "\", all-chars;
all-chars      = ? all unicode characters ?;

If you need to use both single and double quotes inside a quoted argument, then you must escape one of them using \ (backslash). If you want to use \ literally, then double it as \\. Backslash has a special meaning only inside a quoted argument, not in unquoted argument.

Examples

Examples of RSQL expressions in both FIQL-like and alternative notation:

?_filter=name=="Kill Bill";year=gt=2003
?_filter=name=="Kill Bill" and year=gt=2003
?_filter=actor=like=*Bale;year=btw=(2000,2010)
?_filter=actor=like=*Bale and year=btw=(2000,2010)

Paging

Client-side paging

In client-side paging, a client app specifies the number of results it wants to get back in a single page by using the _pageSize query parameter. Then using _pageNo it can control the nth page it wants to being retrieved.

You can get the real items total count using _return_count query parameter.

Synchronize items

This guide describes how to implement “incremental synchronization” of data. Using this method, you can keep data for all items collections in sync while saving bandwidth.

Overview

Incremental synchronization consists of two stages: 1. Initial full sync is performed once at the very beginning in order to fully synchronize the client’s state with the server’s state. The client will obtain a sync-token that it needs to persist. 2. Incremental sync is performed repeatedly and updates the client with all the changes that happened ever since the previous sync. Each time, the client provides the previous sync-token it obtained from the server and stores the new sync-token from the response.

Note

A sync-token is a piece of data exchanged between the server and the client, and has a critical role in the synchronization process. An example would look like the following:

“nextSyncToken”: “CPDAlvWDx70CEPDAlvWDx70CGAU=”,

Initial full sync

The initial full sync is the original request for all the resources of the collection you want to synchronize. You can optionally restrict the list request using request parameters if you only want to synchronize a specific subset of resources.

In the response to the list operation, you will find a field called nextSyncToken representing a sync token. You’ll need to store the value of nextSyncToken.

Incremental sync

Incremental sync allows you to retrieve all the resources that have been modified since the last sync request. To do this, you need to perform a list request with your most recent sync-token specified in the _syncToken parameter.