Skip to content

Commit 7378e52

Browse files
authored
Merge pull request #59 from AddSearch/sc-9487/add-method-to-intercept-api-request
[sc-9487] add setApiRequestInterceptor
2 parents 2338527 + 97b796b commit 7378e52

File tree

9 files changed

+99
-15
lines changed

9 files changed

+99
-15
lines changed

README.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -408,11 +408,30 @@ client.setThrottleTime(500);
408408
```
409409

410410
#### Set API hostname
411+
`option` is an object with the following properties, all of which are optional. If `option` is not defined, host name will be applied for all requests.
412+
- **searchApiRequestOnly**: If true, the new host name is only applied for searchApi requests (default: false)
413+
- **statsApiRequestOnly**: If true, the new host name is only applied for statsApi requests (default: false)
411414
```js
412415
// Set API hostname (e.g. for dedicated environments)
413416
client.setApiHostname('api.addsearch.com');
414417
```
415418

419+
#### Set API request interceptor
420+
`configurationObject` contains 2 keys: <string>`url` and <object>`headers`. Modify the `configurationObject` before it is sent.
421+
422+
`option` is an object with the following properties, all of which are optional. If `option` is not defined, the interceptor will be used for all requests.
423+
- **searchApiRequestOnly**: If true, the interceptor is only used for searchApi requests (default: false)
424+
- **statsApiRequestOnly**: If true, the interceptor is only used for statsApi requests (default: false)
425+
426+
```js
427+
function callback(configurationObject) {
428+
configurationObject.headers['X-Api-Key'] = 'YOUR API KEY';
429+
return configurationObject;
430+
}
431+
client.setApiRequestInterceptor(callback, option);
432+
```
433+
434+
416435
## Indexing API
417436
With the Indexing API, you can fetch, create, update, and delete single documents or
418437
batches of documents.

dist/addsearch-js-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.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "addsearch-js-client",
3-
"version": "0.8.9",
3+
"version": "0.8.10",
44
"description": "AddSearch API JavaScript client",
55
"main": "index.js",
66
"jsdelivr": "./dist/addsearch-js-client.min.js",

src/api.js

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
'use strict';
2+
3+
const axios = require('axios').default;
4+
const apiInstance = axios.create();
5+
const statsInstance = axios.create();
6+
7+
const setRequestInterceptor = (callback, requestType) => {
8+
const axiosInstance = requestType === 'searchApi' ? apiInstance : statsInstance;
9+
axiosInstance.interceptors.request.use( (config) => {
10+
const updatedConfig = callback({
11+
url: config.url,
12+
headers: config.headers
13+
});
14+
config = {...config, ...updatedConfig};
15+
return config;
16+
}, function (error) {
17+
return Promise.reject(error);
18+
});
19+
};
20+
21+
module.exports = {
22+
apiInstance,
23+
statsInstance,
24+
setRequestInterceptor
25+
};

src/apifetch.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
'use strict';
22

33
require('es6-promise').polyfill();
4-
const axios = require('axios').default;
4+
const apiInstance = require('./api').apiInstance;
55

66
/**
77
* Fetch search results of search suggestions from the Addsearch API
@@ -174,7 +174,7 @@ var executeApiFetch = function(apiHostname, sitekey, type, settings, cb, fuzzyRe
174174
'https://' + apiHostname + '/v1/' + apiPath + '/' + sitekey + '?configurationKey=' + recommendOptions.configurationKey + qs :
175175
'https://' + apiHostname + '/v1/' + apiPath + '/' + sitekey + '?term=' + kw + qs;
176176

177-
axios.get(api)
177+
apiInstance.get(api)
178178
.then(function(response) {
179179
var json = response.data;
180180
// Search again with fuzzy=true if no hits

src/index.js

Lines changed: 38 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ var Settings = require('./settings');
77
var util = require('./util');
88
var throttle = require('./throttle');
99
var cookie = require('./cookie');
10+
var setRequestInterceptor = require('./api').setRequestInterceptor;
1011

1112
var API_HOSTNAME = 'api.addsearch.com';
1213
var USER_TOKEN_COOKIE_NAME = 'addsearchUserToken';
@@ -15,6 +16,7 @@ var client = function(sitekey, privatekey) {
1516
this.sitekey = sitekey;
1617
this.privatekey = privatekey;
1718
this.apiHostname = API_HOSTNAME;
19+
this.statsApiHostname = API_HOSTNAME;
1820
this.settings = new Settings();
1921
this.sessionId = ('a-' + (Math.random() * 100000000)).substring(0, 10);
2022
this.userTokenInPersonalization = cookie.getCookie(USER_TOKEN_COOKIE_NAME) || util.generateUUID();
@@ -173,7 +175,14 @@ var client = function(sitekey, privatekey) {
173175
/**
174176
* Public functions
175177
*/
176-
this.setApiHostname = function(hostname) {this.apiHostname = hostname;}
178+
this.setApiHostname = function(hostname, conf) {
179+
if (!conf || !conf.statsApiRequestOnly) {
180+
this.apiHostname = hostname;
181+
}
182+
if (!conf || !conf.searchApiRequestOnly) {
183+
this.statsApiHostname = hostname;
184+
}
185+
}
177186
this.getSettings = function() {return this.settings.getSettings();}
178187
this.setLanguage = function(lang) {this.settings.setLanguage(lang);}
179188
this.setCategoryFilters = function(categories) {this.settings.setCategoryFilters(categories);}
@@ -227,7 +236,7 @@ var client = function(sitekey, privatekey) {
227236
numberOfResults: data.numberOfResults,
228237
tag: this.getSettings().analyticsTag
229238
};
230-
sendStats(this.apiHostname, this.sitekey, payload);
239+
sendStats(this.statsApiHostname, this.sitekey, payload, this.settings.getSettings().statsRequestIntercepted);
231240
}
232241

233242
else if (type === 'click') {
@@ -239,7 +248,7 @@ var client = function(sitekey, privatekey) {
239248
position: data.position,
240249
tag: this.getSettings().analyticsTag
241250
};
242-
sendStats(this.apiHostname, this.sitekey, payload);
251+
sendStats(this.statsApiHostname, this.sitekey, payload, this.settings.getSettings().statsRequestIntercepted);
243252
}
244253

245254
else {
@@ -269,6 +278,32 @@ var client = function(sitekey, privatekey) {
269278
isAddSearchCookieConsented = !!isEnabled;
270279
};
271280

281+
/*
282+
* API interceptor
283+
*/
284+
this.setApiRequestInterceptor = function(callback, option = {}) {
285+
if (typeof callback !== 'function') {
286+
window.console.error('API interceptor must be a function');
287+
return;
288+
}
289+
290+
const { searchApiRequestOnly = false, statsApiRequestOnly = false } = option;
291+
292+
if (!searchApiRequestOnly && !statsApiRequestOnly) {
293+
setRequestInterceptor(callback, 'searchApi');
294+
setRequestInterceptor(callback, 'statsApi');
295+
this.settings.setStatsRequestIntercepted(true);
296+
} else {
297+
if (searchApiRequestOnly) {
298+
setRequestInterceptor(callback, 'searchApi');
299+
}
300+
if (statsApiRequestOnly) {
301+
setRequestInterceptor(callback, 'statsApi');
302+
this.settings.setStatsRequestIntercepted(true);
303+
}
304+
}
305+
};
306+
272307

273308
// Deprecated
274309
this.searchResultClicked = function(documentId, position) {

src/settings.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@ var settings = function() {
2222
},
2323
searchOperator: null,
2424
enableLogicalOperators: false,
25-
cacheResponseTime: null
25+
cacheResponseTime: null,
26+
statsRequestIntercepted: false,
2627
};
2728

2829
this.getSettings = function() {
@@ -232,6 +233,10 @@ var settings = function() {
232233
}
233234
this.settings.searchOperator = operator;
234235
}
236+
237+
this.setStatsRequestIntercepted = function(isIntercepted) {
238+
this.settings.statsRequestIntercepted = isIntercepted;
239+
};
235240
}
236241

237242
module.exports = settings;

src/stats.js

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,23 @@
11
'use strict';
22

33
require('es6-promise').polyfill();
4-
const axios = require('axios').default;
4+
const statsInstance = require('./api').statsInstance;
55

6-
var sendStats = function(apiHostname, sitekey, payload) {
6+
var sendStats = function(apiHostname, sitekey, payload, statsRequestIntercepted) {
77

88
// Beacon in browsers
9-
if (typeof window !== 'undefined' && window.navigator && window.navigator.sendBeacon) {
9+
if (typeof window !== 'undefined' && window.navigator && window.navigator.sendBeacon && !statsRequestIntercepted) {
1010
navigator.sendBeacon('https://' + apiHostname + '/v1/stats/' + sitekey + '/', JSON.stringify(payload));
1111
}
1212

1313
// POST in node
1414
else {
15-
axios.post('https://' + apiHostname + '/v1/stats/' + sitekey + '/', payload, {
15+
statsInstance.post('https://' + apiHostname + '/v1/stats/' + sitekey + '/', payload, {
1616
headers: {
1717
'Content-Type': 'text/plain',
1818
}
1919
});
2020
}
2121
};
2222

23-
module.exports = sendStats;
23+
module.exports = sendStats;

test/apifetch.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
var assert = require('assert');
22
var apifetch = require('../src/apifetch');
33
var MockAdapter = require("axios-mock-adapter");
4-
const axios = require('axios').default;
5-
var mock = new MockAdapter(axios);
4+
var apiInstance = require('../src/api').apiInstance;
5+
var mock = new MockAdapter(apiInstance);
66

77
mock.onAny().reply(200, { response: 200 });
88

0 commit comments

Comments
 (0)