Skip to content

Commit 5ce2758

Browse files
authored
Merge pull request #87 from AddSearch/sc-11931/support-POST-api
[sc-11931] handle POST request payload
2 parents e7c3f54 + f8ba019 commit 5ce2758

File tree

6 files changed

+218
-79
lines changed

6 files changed

+218
-79
lines changed

README.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -532,6 +532,16 @@ callbackFn = function (response) {
532532
client.putSentimentClick('conversation_id', 'sentiment_value');
533533
```
534534

535+
## POST API
536+
:exclamation: POST API is not fully supported. If you need to use some methods in the library, please contact our support.
537+
538+
#### Fetch AI answers
539+
540+
```js
541+
// default method: "GET"
542+
client.setApiMethod('POST');
543+
```
544+
535545
## Indexing API
536546

537547
With the Indexing API, you can fetch, create, update, and delete single documents or batches of

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": "1.0.5",
3+
"version": "1.1.0",
44
"description": "AddSearch API JavaScript client",
55
"repository": {
66
"type": "git",

src/apifetch.ts

Lines changed: 152 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import 'es6-promise/auto';
22
import { apiInstance, RESPONSE_BAD_REQUEST, RESPONSE_SERVER_ERROR } from './api';
33
import { Settings } from './settings';
44
import { AxiosResponse } from 'axios';
5+
import { isEmptyObject } from './util';
56

67
interface RecommendOptions {
78
type: 'RELATED_ITEMS' | 'FREQUENTLY_BOUGHT_TOGETHER';
@@ -121,6 +122,7 @@ const executeApiFetch: ExecuteApiFetch = function (
121122

122123
let keyword = '';
123124
let queryParamsString = '';
125+
let requestPayloadObject = {};
124126

125127
// API Path (eq. /search, /suggest, /autocomplete/document-field)
126128
let apiEndpoint: string | null = null;
@@ -155,6 +157,7 @@ const executeApiFetch: ExecuteApiFetch = function (
155157
}
156158
}
157159

160+
// GET Parameters
158161
queryParamsString =
159162
settingToQueryParam(settings?.lang, 'lang') +
160163
settingToQueryParam(fuzzy, 'fuzzy') +
@@ -176,8 +179,37 @@ const executeApiFetch: ExecuteApiFetch = function (
176179
settingToQueryParam(settings?.searchOperator, 'defaultOperator') +
177180
settingToQueryParam(settings?.analyticsTag, 'analyticsTag');
178181

182+
// POST Parameters
183+
184+
requestPayloadObject = {
185+
...requestPayloadObject,
186+
language: settings?.lang,
187+
fuzzy: fuzzy !== true && fuzzy !== false ? fuzzy : JSON.stringify(fuzzy),
188+
collectAnalytics: settings?.collectAnalytics,
189+
postfixWildcard: settings?.postfixWildcard,
190+
categories: settings?.categories ? settings?.categories.split(',') : undefined,
191+
priceFromCents: settings?.priceFromCents ? parseInt(settings?.priceFromCents, 10) : undefined,
192+
priceToCents: settings?.priceToCents ? parseInt(settings?.priceToCents, 10) : undefined,
193+
dateFrom: settings?.dateFrom,
194+
dateTo: settings?.dateTo,
195+
paging: {
196+
page: settings?.paging.page ?? 1,
197+
pageSize: settings?.paging.pageSize ?? 10,
198+
shuffleAndLimitTo: settings?.shuffleAndLimitTo ?? undefined,
199+
sortByField: settings?.paging.sortBy,
200+
sortOrder: settings?.paging.sortOrder
201+
},
202+
jwt: settings?.jwt,
203+
resultType: settings?.resultType,
204+
userToken: settings?.userToken ?? undefined,
205+
numFacets: settings?.numFacets,
206+
cacheResponseWithTtlSeconds: settings?.cacheResponseTime ?? undefined,
207+
defaultOperator: settings?.searchOperator ?? undefined,
208+
analyticsTag: settings?.analyticsTag
209+
};
210+
179211
// Add sortBy and sortOrder
180-
if (Array.isArray(settings?.paging.sortBy)) {
212+
if (Array.isArray(settings?.paging.sortBy) && settings?.paging.sortBy.length > 1) {
181213
settings?.paging.sortBy.forEach(function (value, index) {
182214
queryParamsString =
183215
queryParamsString +
@@ -193,16 +225,34 @@ const executeApiFetch: ExecuteApiFetch = function (
193225

194226
// Add custom field filters
195227
if (settings?.customFieldFilters) {
228+
const customFieldFiltersValues: any = {};
196229
for (let i = 0; i < settings?.customFieldFilters.length; i++) {
197230
queryParamsString = queryParamsString + '&customField=' + settings?.customFieldFilters[i];
231+
232+
const decodedCustomFieldFilter = decodeURIComponent(settings?.customFieldFilters[i]);
233+
const customFieldFilterPair = decodedCustomFieldFilter.split('=');
234+
const customFieldName = customFieldFilterPair[0];
235+
const customFieldValue = customFieldFilterPair[1];
236+
customFieldFiltersValues[customFieldName] = customFieldValue;
198237
}
238+
239+
requestPayloadObject = {
240+
...requestPayloadObject,
241+
customField: isEmptyObject(customFieldFiltersValues) ? undefined : customFieldFiltersValues
242+
};
199243
}
200244

201245
// Add facet fields
202246
if (settings?.facetFields) {
247+
const facetFieldsValues: string[] = [];
203248
for (let i = 0; i < settings?.facetFields.length; i++) {
204249
queryParamsString = queryParamsString + '&facet=' + settings?.facetFields[i];
250+
facetFieldsValues.push(settings?.facetFields[i]);
205251
}
252+
requestPayloadObject = {
253+
...requestPayloadObject,
254+
facet: facetFieldsValues.length > 0 ? facetFieldsValues : undefined
255+
};
206256
}
207257

208258
// Range facets
@@ -211,6 +261,10 @@ const executeApiFetch: ExecuteApiFetch = function (
211261
queryParamsString +
212262
'&rangeFacets=' +
213263
encodeURIComponent(JSON.stringify(settings?.rangeFacets));
264+
requestPayloadObject = {
265+
...requestPayloadObject,
266+
rangeFacets: settings?.rangeFacets
267+
};
214268
}
215269

216270
// Hierarchical facets
@@ -219,32 +273,56 @@ const executeApiFetch: ExecuteApiFetch = function (
219273
queryParamsString +
220274
'&hierarchicalFacets=' +
221275
encodeURIComponent(JSON.stringify(settings?.hierarchicalFacetSetting));
276+
requestPayloadObject = {
277+
...requestPayloadObject,
278+
hierarchicalFacets: settings?.hierarchicalFacetSetting
279+
};
222280
}
223281

224282
// Stats fields
225283
if (settings?.statsFields) {
284+
const statsFieldsValues: string[] = [];
226285
for (let i = 0; i < settings?.statsFields.length; i++) {
227286
queryParamsString = queryParamsString + '&fieldStat=' + settings?.statsFields[i];
287+
statsFieldsValues.push(settings?.statsFields[i]);
228288
}
289+
requestPayloadObject = {
290+
...requestPayloadObject,
291+
statsFields: statsFieldsValues
292+
};
229293
}
230294

231295
// Personalization events
232296
if (settings?.personalizationEvents && Array.isArray(settings?.personalizationEvents)) {
297+
const personalizationEventsValues: any[] = [];
233298
for (let i = 0; i < settings?.personalizationEvents.length; i++) {
234299
const obj = settings?.personalizationEvents[i];
235300
const key = Object.keys(obj)[0];
236301
queryParamsString =
237302
queryParamsString + '&personalizationEvent=' + encodeURIComponent(key + '=' + obj[key]);
303+
personalizationEventsValues.push(obj);
238304
}
305+
requestPayloadObject = {
306+
...requestPayloadObject,
307+
personalizationEvents: personalizationEventsValues
308+
};
239309
}
240310

241311
// Filter object
242312
if (customFilterObject) {
243313
queryParamsString =
244314
queryParamsString + '&filter=' + encodeURIComponent(JSON.stringify(customFilterObject));
315+
requestPayloadObject = {
316+
...requestPayloadObject,
317+
filter: customFilterObject
318+
};
245319
} else if (settings?.filterObject) {
246320
queryParamsString =
247321
queryParamsString + '&filter=' + encodeURIComponent(JSON.stringify(settings?.filterObject));
322+
requestPayloadObject = {
323+
...requestPayloadObject,
324+
filter: isEmptyObject(settings?.filterObject) ? undefined : settings?.filterObject
325+
};
248326
}
249327

250328
apiEndpoint =
@@ -295,6 +373,12 @@ const executeApiFetch: ExecuteApiFetch = function (
295373
queryParamsString =
296374
settingToQueryParam(settings?.suggestionsSize, 'size') +
297375
settingToQueryParam(settings?.lang, 'language');
376+
requestPayloadObject = {
377+
...requestPayloadObject,
378+
size: settings?.suggestionsSize,
379+
language: settings?.lang
380+
};
381+
298382
keyword = settings?.suggestionsPrefix as string;
299383
apiEndpoint =
300384
'https://' +
@@ -325,6 +409,12 @@ const executeApiFetch: ExecuteApiFetch = function (
325409
'?term=' +
326410
keyword +
327411
queryParamsString;
412+
413+
requestPayloadObject = {
414+
...requestPayloadObject,
415+
source: settings?.autocomplete.field,
416+
size: settings?.autocomplete.size
417+
};
328418
} else if (type === 'recommend') {
329419
if (recommendOptions?.type === 'RELATED_ITEMS') {
330420
queryParamsString = settingToQueryParam(recommendOptions.itemId, 'itemId');
@@ -335,6 +425,12 @@ const executeApiFetch: ExecuteApiFetch = function (
335425
recommendOptions.blockId +
336426
'?' +
337427
queryParamsString;
428+
429+
requestPayloadObject = {
430+
...requestPayloadObject,
431+
itemId: recommendOptions.itemId ?? undefined,
432+
blockId: recommendOptions.blockId
433+
};
338434
} else if (recommendOptions?.type === 'FREQUENTLY_BOUGHT_TOGETHER') {
339435
queryParamsString = settingToQueryParam(recommendOptions.itemId, 'itemId');
340436
apiPath =
@@ -343,49 +439,70 @@ const executeApiFetch: ExecuteApiFetch = function (
343439
'?configurationKey=' +
344440
recommendOptions.configurationKey +
345441
queryParamsString;
442+
443+
requestPayloadObject = {
444+
...requestPayloadObject,
445+
itemId: recommendOptions.itemId ?? undefined,
446+
configurationKey: recommendOptions.configurationKey
447+
};
346448
}
347449
apiEndpoint = 'https://' + apiHostname + '/v1/' + apiPath;
348450
}
349451

452+
// Handle API response for all types except ai-answers
350453
if (type !== 'ai-answers') {
351-
apiInstance
352-
.get(apiEndpoint as string)
353-
.then(function (response: AxiosResponse<GenericApiResponse>) {
354-
const json = response.data;
355-
356-
// Search again with fuzzy=true if no hits
357-
if (
358-
type === 'search' &&
359-
settings?.fuzzy === 'retry' &&
360-
json.total_hits === 0 &&
361-
fuzzyRetry !== true
362-
) {
363-
executeApiFetch(apiHostname, sitekey, type, settings, cb, true);
454+
const handleApiResponse = function (response: AxiosResponse<GenericApiResponse>) {
455+
const json = response.data;
456+
457+
// Search again with fuzzy=true if no hits
458+
if (
459+
type === 'search' &&
460+
settings?.fuzzy === 'retry' &&
461+
json.total_hits === 0 &&
462+
fuzzyRetry !== true
463+
) {
464+
executeApiFetch(apiHostname, sitekey, type, settings, cb, true);
465+
} else {
466+
// Cap fuzzy results to one page as quality decreases quickly
467+
if (fuzzyRetry === true) {
468+
json.total_hits = Math.min(
469+
json.total_hits ?? Infinity,
470+
settings?.paging?.pageSize ?? Infinity
471+
);
364472
}
365-
// Fuzzy not "retry" OR fuzzyRetry already returning
366-
else {
367-
// Cap fuzzy results to one page as quality decreases quickly
368-
if (fuzzyRetry === true) {
369-
json.total_hits = Math.min(
370-
json.total_hits ?? Infinity,
371-
settings?.paging?.pageSize ?? Infinity
372-
);
373-
}
374473

375-
// Callback
376-
cb(json);
474+
// Callback
475+
cb(json);
476+
}
477+
};
478+
479+
const handleApiError = function (error: any) {
480+
console.error(error);
481+
cb({
482+
error: {
483+
response: RESPONSE_SERVER_ERROR,
484+
message: 'invalid server response'
377485
}
378-
})
379-
.catch(function (error) {
380-
console.error(error);
381-
382-
cb({
383-
error: {
384-
response: RESPONSE_SERVER_ERROR,
385-
message: 'invalid server response'
386-
}
387-
});
388486
});
487+
};
488+
489+
if (settings?.apiMethod === 'POST' && ['search', 'suggest', 'autocomplete'].includes(type)) {
490+
apiEndpoint = 'https://' + apiHostname + '/v1/' + apiPath + '/' + sitekey;
491+
const term = type === 'search' ? decodeURIComponent(keyword) : keyword;
492+
requestPayloadObject = {
493+
term,
494+
...requestPayloadObject
495+
};
496+
apiInstance
497+
.post(apiEndpoint, requestPayloadObject)
498+
.then(handleApiResponse)
499+
.catch(handleApiError);
500+
} else {
501+
apiInstance
502+
.get(apiEndpoint as string)
503+
.then(handleApiResponse)
504+
.catch(handleApiError);
505+
}
389506
}
390507
};
391508

0 commit comments

Comments
 (0)