JavaScript

Batch

The Ably REST API enables certain operations to be executed in batch. Batch mode queries an API multiple times with single HTTP request. The operations that have a batch option are publishing messages and retrieving the presence state for a set of channels.

A batch request has a single set of request details containing the request body, parameters and headers and converts them into an array of requests to the underlying API. Each individual request to the underlying API is performed in parallel and may succeed or fail independently.

Note: All batch requests are limited to querying 100 different channels per request.

Once all requests have been completed, a batch response is returned with three possible outcomes:

If all of the individual requests were successful then an array containing the response of each query is returned in request order.

If the batch request itself failed before the individual requests were made, then an error response is returned with a status code and error response body. Examples of why the batch request can fail include an authorization failure or an invalid request.

If one or more of the individual requests failed the response body contains an error object with the error code 40020 and a status code of 400. The error body contains a batchResponse array of each individual response in request order.

The batchResponse can be inspected if there is a need to know the details of each outcome. If you only need to know whether or not the batch request was completely successful then the status code is sufficient.

The batch publish endpoint enables you to publish messages to multiple channels with a single request.

Note: The maximum request body size for batch publishing is 2MiB.

var ablyRest = new Ably.Rest({ key: '<loading API key, please wait>' }) var content = { "channels": [ "test1", "test2" ], "messages": { "data": 'myData' } } ablyRest.request('post', '/messages', null, content, null, function(err, response) { if(err) { alert('An error occurred; err = ' + err.toString()); } else { alert('Success! status code was ' + response.statusCode); } });
Demo Only
Copied!

Batch publish uses the request method to query the batch REST API.

Each batch publish request can contain a single BatchSpec object, or an array of BatchSpec objects. Each BatchSpec object contains a single channel name or an array of channel names in the channels property and a single message or array of messages in the messages property.

This means that in a single request N number of messages can be published to N number of channels.

Note: If the same channel name appears in multiple BatchSpec objects within a single request, it only counts as one channel towards the 100 channel limit per batch request.

Note: The total size of all messages in a messages array of a BatchSpec object must be less than the message limit for each channel. If the total message size exceeds the limit for a single channel then the messages can be split into multiple BatchSpec objects instead.

The following is an example of a single BatchSpec object publishing a single message to 2 channels:

{ channels: ['channel1', 'channel2'], messages: {data: 'My message contents'} }
Copied!

The following is an example of an array of BatchSpec objects. The first publishes a single message to two channels and the second publishes two messages to a single channel:

[ { channels: ['channel1', 'channel2'], messages: {data: 'My message contents'} }, { channels: 'channel3', messages: [ {data: 'My message contents'}, {name: 'an event', data: 'My event message contents'}, ] } ]
Copied!

The following is an example curl request, querying the REST API directly:

curl -X POST https://rest.ably.io/messages \ -u "<loading API key, please wait>" \ -H "Content-Type: application/json" \ --data '{ "channels": [ "test1", "test2"], "messages": {"data": "My test message text" } }'
Demo Only
Copied!

A batch publish request can succeed, fail or partially succeed. The response returned will differ depending on the outcome.

The examples for each possible outcome will use the following BatchSpec object as the request data:

{ channels: ['channel0', 'channel1', 'channel2'], messages: {data: 'My test message text'} }
Copied!

The following is an example of a successful batch publish response. The response body contains the messageId of each published message and the channel it was published to. The status code is 201:

[ { "channel":"channel0", "messageId":"w234r5t-fr5" }, { "channel":"channel1", "messageId":"vde4sfc0p" }, { "channel":"channel2", "messageId":"nh3exv8ih" } ]
Copied!

The following is an example of a batch publish failure response. The response body contains the details of the error, in this example that the token used for the request has expired. The status code is 401:

{ "error": { "message":"Token expired", "statusCode":401, "code":40140 } }
Copied!

The following is an example of a batch publish partial success response. The successful requests contain the messageId of each published message and the channel they were published to. The failed request contains the channel the request failed for and the details of the error, in this example that the credentials used didn’t have the capability to publish to that channel. The status code for a partial success is always 400:

{ "error": { "message": "Batched response includes errors", "statusCode":400, "code":40020 } "batchResponse": [ { "channel":"channel0", "messageId":"w234r5t-fr5" }, { "channel":"channel1", "messageId":"vde4sfc0p" }, { "channel":"channel2", "error": { "message": "Given credentials do not have the required capability", "statusCode": 401, "code": 40160 } } ] }
Copied!

The batch presence endpoint enables you to retrieve the presence state for multiple channels with a single request. The presence state contains details about the clients in the presence set, such as their clientId, member data and presence action.

var ablyRest = new Ably.Rest({ key: '<loading API key, please wait>' }) var content = { "channel": "channel1,channel2" } ablyRest.request('GET', '/presence', content, null, {}, function(err, response) { if(err) { alert('An error occurred; err = ' + err.toString()); } else { alert('Success! status code was ' + response.statusCode); } });
Demo Only
Copied!

Batch presence uses the request method to query the batch REST API.

A batch presence request contains a comma separated list of channel names with no spaces.

The following is an example of a batch presence request for 2 channels:

{ channel: 'channel1,channel2' }
Copied!

The following is an example curl request, querying the REST API directly:

curl -X GET https://rest.ably.io/presence?channel=channel1,channel2 \ -u "<loading API key, please wait>"
Demo Only
Copied!

A batch presence request can succeed, fail or partially succeed. The response returned will differ depending on the outcome. Any successful requests will return details of the clients present on each channel.

The examples for each possible outcome will use the following request data:

{ channel: 'channel0,channel1,channel2' }
Copied!

The following is an example of a successful batch presence response. The response body contains details of each client present on the channel and the channel they are present on. The status code for a successful response is always 200:

[ { "channel":"channel0", <a href="[">presence</a> {"clientId": "user1", "action": "1"}, {"clientId": "user2", "action": "1"} ] }, { "channel":"channel1", <a href="[">presence</a>] }, { "channel":"channel2", <a href="[">presence</a> {"clientId": "user2", "action": "1"}, {"clientId": "user3", "action": "1"} ] } ]
Copied!

The following is an example of a batch presence failure response. The response body contains the details of the error, in this example that the token used for the request has expired. The status code is 401:

{ "error": { "message":"Token expired", "statusCode":401, "code":40140 } }
Copied!

The following is an example of a batch presence partial success response. The successful requests contain the details of each client present on the channel and the channel they are present on. The failed request contains the channel the request failed for and the details of the error, in this example that the credentials used didn’t have the capability to query that channel. The status code for a partial success is always 400:

{ "error": { "message": "Batched response includes errors", "statusCode":400, "code":40020 } "batchResponse": [ { "channel":"channel0", <a href="[">presence</a> {"clientId": "user1", "action": "1"}, {"clientId": "user2", "action": "1"} ] }, { "channel":"channel1", <a href="[">presence</a>] }, { "channel":"channel2", "error": { "message": "Given credentials do not have the required capability", "statusCode": 401, "code": 40160 } } ] }
Copied!

Using the request method in an Ably Rest Client Library SDK requires handling responses for success, failure and partial success.

A response object will have response.success set to true if the batch presence request was successful, and false if at least one individual presence request failed. The response.statusCode will be set to 200 for success, 400 for partial success and 401 for an expected failure. response.errorCode will then contain the Ably error code and response.errorMessage will contain the details of the error.

response.items will contain a list of responses for each channel for which presence has been requested in a successful response. response.items.batchResponse will contain a list of each channel’s results, be it an error or a success for a partially successful response. The response.errorCode will always be 40020 for a partial success.

The following is an example of handling the various responses:

var ablyRest = new Ably.Rest({ key: '<loading API key, please wait>' }) var content = { "channel": "channel1,channel2" } ablyRest.request('GET', '/presence', content, null, {}, function(err, response) { if(err) { // Throw error } else { if(response.success) { // If complete success for(i = 0; i < response.items.length; i++) { // Each response item will be roughly of the style: /* { "channel": "channel1", "presence": [ { "action": 1, "clientId": "CLIENT1" }, { "action": 1, "clientId": "CLIENT2" } ] } */ } } else if(response.errorCode === 40020) { // If partial success for(i = 0; i < response.items[0].batchResponse.length; i++) { // Each batchResponse item will either be the same as success if it succeeded, or: /* { "channel": "channel1", "error": { "code": 40160, "message": "ERROR_MESSAGE", "statusCode": 401 } } */ } } else { // If failed, check why console.log(response.errorCode + ', ' + response.errorMessage); } } });
Demo Only
Copied!