There are two relevant types of REST API resources for retrieving events through the REST API: subscriptions and events. One or more subscriptions need to exist for the event types that the application wishes to receive. This will cause the Brain to buffer these types of events, which can then be queried by the application through the events resource.
Creating a subscription
A new Brain will contain a few subscriptions by default; these can be listed with a GET request on /api/subscriptions
. If these subscriptions do not cover the events required by the application, additional subscriptions can be created with POST requests. At minimum, the subscription needs a topic filter that determines which kind of events it will capture. Another important property is the hold time, which determines for how long the events will be buffered. The application needs to retrieve and process the events within this time because they will be deleted once the hold time expires.
For example, this cURL command would create a subscription for "Smartspot connected to the Brain" events, keeping them for 24 hours:
curl --request POST --data '{"topic_filter": "spots/+/connected/#", "database_hold_time_h": 24}' --header "Content-Type: application/json" --header "X-Api-Key: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" https://<brain-host>/api/subscriptions
Subscriptions are permanent until manually removed with a DELETE request. Therefore they only need to be created once.
See the subscriptions resource documentation for more information about subscription parameters. The topic filter format is detailed in Filtering events.
Retrieving events
The general process of polling events is as follows:
- Request the most recent event and consider that the last processed event.
- Request and process events newer than the last processed event.
- If there were events to process, start again from (2) immediately. Otherwise, start again from (2) after a delay.
Events can be requested using a GET request on either of two different REST API endpoints: one for events captured by a specific subscription, the other for all events of all subscriptions. Which of these to use is a matter of preference.
Endpoint for all events: /api/events
Endpoint for events of a single subscription: /api/subscriptions/<subscription-id>/events
Details about these endpoints can be found in the events resource documentation.
Determining the most recent event
API results are ordered from newest to oldest by default. Therefore, the most recent event ID can be found by GETting the endpoint and taking the ID of the first result. If there are zero results (i.e. the first event has yet to occur), the event ID should be omitted in the next step ("Checking for new events").
The application could determine the most recent event every time it starts, or persistently store (and later update) the latest processed ID and load this stored ID every time it starts. Such an implementation would allow the application to catch up on missed events if it experiences downtime.
Checking for new events
To check for new events, the endpoint is queried from oldest to newest instead. This can be done by adding the query parameter sort=id
. This sorts the results on the ID field (which is always chronological) in ascending order. Furthermore, the most recently processed event should be specified in the query parameter after_id
. For example:
GET /api/events?sort=id&after_id=d9bf2dd9643d48b515bc90a3
The results can then be processed in order. The ID of the last result should be used as the last processed event ID for the next request. If there are zero results, no new events have occurred since the last request and it can be repeated with the same after_id
value after a reasonable delay.
Pseudocode example
The following pseudocode illustrates a possible implementation outline for retrieving events with REST API polling as explained in this article.
latestEventId = null response = jsonDecode(brainApiGetRequest('/events')) if (response.results.length > 0) { latestEventId = response.results[0].id } while (true) {
endpoint = "/events?sort=id"
if (latestEventId != null) {
endpoint = endpoint + "&after_id=" + latestEventId
} response = jsonDecode(brainApiGetRequest(endpoint)) for (event in response.results) {
processEvent(event) latestEventId = event.id }
if (response.results.length == 0) {
delayMilliseconds(5000)
} }
Comments
0 comments
Article is closed for comments.