Skip to content

Commit ec23755

Browse files
committed
Support Batch endpoint
1 parent 9478225 commit ec23755

File tree

9 files changed

+159
-8
lines changed

9 files changed

+159
-8
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ The library is [UMD](https://github.com/umdjs/umd) compatible.
1515
You can download [recombee-api-client.min.js](./dist/recombee-api-client.min.js) and host it at your site, or use a CDN such as [jsDelivr](https://www.jsdelivr.com/) CDN:
1616

1717
```js
18-
<script src="https://cdn.jsdelivr.net/gh/recombee/[email protected].0/dist/recombee-api-client.min.js"></script>
18+
<script src="https://cdn.jsdelivr.net/gh/recombee/[email protected].1/dist/recombee-api-client.min.js"></script>
1919
```
2020

2121
### npm
@@ -189,7 +189,7 @@ Let's assume we want to show recommendations at product page of pants `product-2
189189
</div>
190190
</div>
191191

192-
<script src="https://cdn.jsdelivr.net/gh/recombee/[email protected].0/dist/recombee-api-client.min.js"></script>
192+
<script src="https://cdn.jsdelivr.net/gh/recombee/[email protected].1/dist/recombee-api-client.min.js"></script>
193193

194194
<script type="text/javascript">
195195

dist/recombee-api-client.js

Lines changed: 63 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/recombee-api-client.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/recombee-api-client.min.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/recombee-api-client.min.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "recombee-js-api-client",
3-
"version": "4.1.0",
3+
"version": "4.1.1",
44
"description": "Client-side js library for easy use of the Recombee recommendation API",
55
"browser": "./src/index.js",
66
"repository": {

src/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,4 @@ exports.RecommendItemSegmentsToItem = require("./requests/recommend-item-segment
2222
exports.RecommendItemSegmentsToItemSegment = require("./requests/recommend-item-segments-to-item-segment").RecommendItemSegmentsToItemSegment;
2323
exports.SearchItems = require("./requests/search-items").SearchItems;
2424
exports.SearchItemSegments = require("./requests/search-item-segments").SearchItemSegments;
25+
exports.Batch = require("./requests/batch").Batch;

src/requests/batch.js

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
'use strict';
2+
const rqs = require("./request");
3+
4+
var sum_timeouts = ((requests) => {
5+
return requests.map((r) => r.timeout).reduce((a, b) => a + b, 0);
6+
});
7+
8+
/**
9+
* In many cases, it may be desirable to execute multiple requests at once. For example, when synchronizing the catalog of items in a periodical manner, you would have to execute a sequence of thousands of separate POST requests, which is very ineffective and may take a very long time to complete. Most notably, network latencies can make execution of such sequence very slow and even if executed in multiple parallel threads, there will still be unreasonable overhead caused by the HTTP(s). To avoid the mentioned problems, batch processing may be used, encapsulating a sequence of requests into a single HTTPS request.
10+
* Batch processing allows you to submit arbitrary sequence of requests and the batch may combine different types of requests arbitrarily as well.
11+
* Note that the status code of the batch request itself is 200 even if the individual requests result in error – you have to inspect the code values in the resulting array.
12+
*/
13+
class Batch extends rqs.Request {
14+
15+
/**
16+
* Construct the request
17+
* @param {Request[]} requests - Array containing the requests.
18+
* @param {Object} optional - Optional parameters given as an object with structure name of the parameter: value
19+
* - Allowed parameters:
20+
* - *distinctRecomms*
21+
* - Type: boolean
22+
* - Description: Makes all the recommended items for a certain user distinct among multiple recommendation requests in the batch.
23+
*/
24+
constructor(requests, optional) {
25+
super('POST', '/batch/', sum_timeouts(requests), true);
26+
this.requests = requests;
27+
optional = optional || {};
28+
this.distinctRecomms = optional.distinctRecomms;
29+
}
30+
31+
/**
32+
* Get body parameters
33+
* @return {Object} The values of body parameters (name of parameter: value of the parameter)
34+
*/
35+
bodyParameters() {
36+
let reqs = this.requests.map((r) => this._request_to_batch_object(r));
37+
let result = {requests: reqs};
38+
39+
if(this.distinctRecomms !== undefined)
40+
result.distinctRecomms = this.distinctRecomms;
41+
42+
return result;
43+
}
44+
45+
_request_to_batch_object(req) {
46+
const bodyParameters = req.bodyParameters();
47+
return {
48+
method: req.method,
49+
path: req.path,
50+
params: Object.keys(bodyParameters).length ? bodyParameters : undefined,
51+
};
52+
}
53+
54+
}
55+
56+
exports.Batch = Batch

tests/tests.js

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ function createClient() {
33
}
44

55
function testInteractionPromise(assert, interactionReq) {
6-
assert.timeout(1000);
6+
assert.timeout(3000);
77
var done = assert.async();
88

99
var client = createClient();
@@ -19,7 +19,7 @@ function testInteractionPromise(assert, interactionReq) {
1919
}
2020

2121
function testInteractionCallback(assert, interactionReq) {
22-
assert.timeout(1000);
22+
assert.timeout(3000);
2323
var done = assert.async();
2424

2525
function callback(err, res) {
@@ -157,4 +157,35 @@ QUnit.test("RecommendItemSegmentsToItemSegment test", function( assert ) {
157157

158158
QUnit.test("SearchItemSegments test", function( assert ) {
159159
testRecommendations(assert, new recombee.SearchItemSegments('user-1', 'computer', 5, {scenario: 's-is'}));
160+
});
161+
162+
163+
QUnit.test("Batch test", function( assert ) {
164+
const req = new recombee.Batch([new recombee.AddBookmark('user-1', 'item-1'),
165+
new recombee.AddCartAddition('user-1', 'item-1'),
166+
new recombee.AddPurchase('user-1', 'item-1'),
167+
new recombee.AddRating('user-1', 'item-1', -1),
168+
new recombee.RecommendItemsToUser('user-1', 5),
169+
new recombee.RecommendItemsToItem('item-1', 'user-1', 5),
170+
new recombee.SearchItems('user-1', 'computer', 5),
171+
new recombee.RecommendItemSegmentsToUser('user-1', 5, {scenario: 'is-to-u'}),
172+
new recombee.RecommendItemSegmentsToItem('item-1', 'user-1', 5, {scenario: 'is-to-i'}),
173+
new recombee.RecommendItemSegmentsToItemSegment('5', 'user-1', 5, {scenario: 'is-to-is'}),
174+
new recombee.SearchItemSegments('user-1', 'computer', 5, {scenario: 's-is'})
175+
]);
176+
177+
assert.timeout(10000);
178+
var done = assert.async();
179+
180+
var client = createClient();
181+
client.send(req)
182+
.then(function(res) {
183+
res.forEach(requestRes => assert.ok(200 <= requestRes.code && requestRes.code <= 299));
184+
done();
185+
})
186+
.catch(function(err) {
187+
assert.ok( false, "Sending Batch should not throw" );
188+
done();
189+
})
190+
160191
});

0 commit comments

Comments
 (0)