Skip to content
This repository was archived by the owner on May 28, 2023. It is now read-only.

Commit dfada8a

Browse files
authored
Merge pull request #390 from DivanteLtd/feature/2167
feature/2167
2 parents 7a97ad4 + 50fd3b2 commit dfada8a

File tree

25 files changed

+226
-260
lines changed

25 files changed

+226
-260
lines changed

CHANGELOG.md

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
99

1010
### Added
1111
- Add url module - @gibkigonzo (#3942)
12-
13-
### Fixed
14-
15-
### Changed / Improved
16-
12+
- The `response_format` query parameter to the `/api/catalog` endpoint. Currently there is just one additional format supported: `response_format=compact`. When used, the response format got optimized by: a) remapping the results, removing the `_source` from the `hits.hits`; b) compressing the JSON fields names according to the `config.products.fieldsToCompact`; c) removing the JSON fields from the `product.configurable_children` when their values === parent product values; overall response size reduced over -70% - @pkarw
13+
- The support for `SearchQuery` instead of the ElasticSearch DSL as for the input to `/api/catalog` - using `storefront-query-builder` package - @pkarw - https://github.com/DivanteLtd/vue-storefront/issues/2167
1714

1815
## [1.11.0] - 2019.12.20
1916

config/default.json

Lines changed: 80 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,83 @@
3636
"taxrule",
3737
"review"
3838
],
39-
"apiVersion": "5.6"
39+
"apiVersion": "5.6",
40+
41+
"searchScoring": {
42+
"attributes": {
43+
"attribute_code": {
44+
"scoreValues": { "attribute_value": { "weight": 1 } }
45+
}
46+
},
47+
"fuzziness": 2,
48+
"cutoff_frequency": 0.01,
49+
"max_expansions": 3,
50+
"minimum_should_match": "75%",
51+
"prefix_length": 2,
52+
"boost_mode": "multiply",
53+
"score_mode": "multiply",
54+
"max_boost": 100,
55+
"function_min_score": 1
56+
},
57+
"searchableAttributes": {
58+
"name": {
59+
"boost": 4
60+
},
61+
"sku": {
62+
"boost": 2
63+
},
64+
"category.name": {
65+
"boost": 1
66+
}
67+
}
68+
},
69+
"products": {
70+
"fieldsToCompress": ["max_regular_price", "max_price", "max_regular_price", "minimal_regular_price", "final_price", "price", "special_price", "original_final_price", "original_price", "original_special_price", "final_price_incl_tax", "price_incl_tax", "special_price_incl_tax", "final_price_tax", "price_tax", "special_price_tax", "image", "small_image", "thumbnail"],
71+
"fieldsToCompact": {
72+
"minimal_price": "mp",
73+
"has_options": "ho",
74+
"url_key": "u",
75+
"status": "s",
76+
"required_options": "ro",
77+
"name": "nm",
78+
"tax_class_id": "tci",
79+
"description": "desc",
80+
"minimal_regular_price": "mrp",
81+
"final_price": "fp",
82+
"price": "p",
83+
"special_price": "sp",
84+
"original_final_price": "ofp",
85+
"original_price": "op",
86+
"original_special_price": "osp",
87+
"final_price_incl_tax": "fpit",
88+
"original_price_incl_tax": "opit",
89+
"price_incl_tax": "pit",
90+
"special_price_incl_tax": "spit",
91+
"final_price_tax": "fpt",
92+
"price_tax": "pt",
93+
"special_price_tax": "spt",
94+
"original_price_tax": "opt",
95+
"image": "i",
96+
"small_image": "si",
97+
"thumbnail": "t"
98+
},
99+
"filterFieldMapping": {
100+
"category.name": "category.name.keyword"
101+
},
102+
"filterAggregationSize": {
103+
"default": 10,
104+
"size": 10,
105+
"color": 10
106+
},
107+
"priceFilterKey": "final_price",
108+
"priceFilters": {
109+
"ranges": [
110+
{ "from": 0, "to": 50 },
111+
{ "from": 50, "to": 100 },
112+
{ "from": 100, "to": 150 },
113+
{ "from": 150 }
114+
]
115+
}
40116
},
41117
"redis": {
42118
"host": "localhost",
@@ -76,7 +152,7 @@
76152
"tax": {
77153
"defaultCountry": "DE",
78154
"defaultRegion": "",
79-
"deprecatedPriceFieldsSupport": true,
155+
"deprecatedPriceFieldsSupport": false,
80156
"calculateServerSide": true,
81157
"sourcePriceIncludesTax": false,
82158
"finalPriceIncludesTax": true,
@@ -113,7 +189,7 @@
113189
"defaultRegion": "",
114190
"calculateServerSide": true,
115191
"sourcePriceIncludesTax": false,
116-
"deprecatedPriceFieldsSupport": true,
192+
"deprecatedPriceFieldsSupport": false,
117193
"finalPriceIncludesTax": true,
118194
"userGroupId": null,
119195
"useOnlyDefaultUserGroupId": false
@@ -143,7 +219,7 @@
143219
"usePlatformTotals": true,
144220
"setConfigurableProductOptions": true,
145221
"sourcePriceIncludesTax": false,
146-
"deprecatedPriceFieldsSupport": true,
222+
"deprecatedPriceFieldsSupport": false,
147223
"finalPriceIncludesTax": false,
148224
"userGroupId": null,
149225
"useOnlyDefaultUserGroupId": false

nodemon.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"verbose": true,
33
"debug": false,
4-
"exec": "ts-node src",
4+
"exec": "node -r ts-node/register src/",
55
"watch": ["./src"],
66
"ext": "ts, js",
77
"inspect": true

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@
9696
"resource-router-middleware": "^0.6.0",
9797
"sharp": "^0.23.4",
9898
"soap": "^0.25.0",
99+
"storefront-query-builder": "^0.0.9",
99100
"syswide-cas": "latest",
100101
"winston": "^2.4.2"
101102
},
@@ -122,7 +123,7 @@
122123
"ts-jest": "^24.0.2",
123124
"ts-node": "^8.1.0",
124125
"tslib": "^1.9.3",
125-
"typescript": "3.3.*"
126+
"typescript": "3.7.*"
126127
},
127128
"bugs": {
128129
"url": "https://github.com/DivanteLtd/vue-storefront-api/issues"
File renamed without changes.

src/api/catalog.js renamed to src/api/catalog.ts

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ import ProcessorFactory from '../processor/factory';
44
import { adjustBackendProxyUrl } from '../lib/elastic'
55
import cache from '../lib/cache-instance'
66
import { sha3_224 } from 'js-sha3'
7+
import bodybuilder from 'bodybuilder'
8+
import { elasticsearch, SearchQuery } from 'storefront-query-builder'
79

810
function _cacheStorageHandler (config, result, hash, tags) {
911
if (config.server.useOutputCache && cache) {
@@ -17,7 +19,23 @@ function _cacheStorageHandler (config, result, hash, tags) {
1719
}
1820
}
1921

20-
export default ({config, db}) => function (req, res, body) {
22+
function _outputFormatter (responseBody, format = 'standard') {
23+
if (format === 'compact') { // simple formatter
24+
delete responseBody.took
25+
delete responseBody.timed_out
26+
delete responseBody._shards
27+
if (responseBody.hits) {
28+
delete responseBody.hits.max_score
29+
responseBody.total = responseBody.hits.total
30+
responseBody.hits = responseBody.hits.hits.map(hit => {
31+
return Object.assign(hit._source, { _score: hit._score })
32+
})
33+
}
34+
}
35+
return responseBody
36+
}
37+
38+
export default ({config, db}) => async function (req, res, body) {
2139
let groupId = null
2240

2341
// Request method handling: exit if not GET or POST
@@ -26,15 +44,19 @@ export default ({config, db}) => function (req, res, body) {
2644
throw new Error('ERROR: ' + req.method + ' request method is not supported.')
2745
}
2846

29-
let requestBody = {}
47+
let responseFormat = 'standard'
48+
let requestBody = req.body
3049
if (req.method === 'GET') {
3150
if (req.query.request) { // this is in fact optional
3251
requestBody = JSON.parse(decodeURIComponent(req.query.request))
3352
}
34-
} else {
35-
requestBody = req.body
3653
}
3754

55+
if (req.query.request_format === 'search-query') { // search query and not Elastic DSL - we need to translate it
56+
requestBody = await elasticsearch.buildQueryBodyFromSearchQuery({ config, queryChain: bodybuilder(), searchQuery: new SearchQuery(requestBody) })
57+
}
58+
if (req.query.response_format) responseFormat = req.query.response_format
59+
3860
const urlSegments = req.url.split('/');
3961

4062
let indexName = ''
@@ -108,15 +130,15 @@ export default ({config, db}) => function (req, res, body) {
108130
resultProcessor.process(_resBody.hits.hits, groupId).then((result) => {
109131
_resBody.hits.hits = result
110132
_cacheStorageHandler(config, _resBody, reqHash, tagsArray)
111-
res.json(_resBody);
133+
res.json(_outputFormatter(_resBody, responseFormat));
112134
}).catch((err) => {
113135
console.error(err)
114136
})
115137
} else {
116138
resultProcessor.process(_resBody.hits.hits).then((result) => {
117139
_resBody.hits.hits = result
118140
_cacheStorageHandler(config, _resBody, reqHash, tagsArray)
119-
res.json(_resBody);
141+
res.json(_outputFormatter(_resBody, responseFormat));
120142
}).catch((err) => {
121143
console.error(err)
122144
})
File renamed without changes.

src/api/index.js renamed to src/api/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ export default ({ config, db }) => {
3838
api.use('/sync', sync({ config, db }))
3939

4040
// mount the url resource
41-
api.use('/url', url({ config, db }))
41+
api.use('/url', url({ config }))
4242

4343
// perhaps expose some API metadata at the root
4444
api.get('/', (req, res) => {

src/api/invalidate.js renamed to src/api/invalidate.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,23 +4,23 @@ import cache from '../lib/cache-instance'
44
import request from 'request'
55

66
function invalidateCache (req, res) {
7-
if (config.server.useOutputCache) {
7+
if (config.get('server.useOutputCache')) {
88
if (req.query.tag && req.query.key) { // clear cache pages for specific query tag
9-
if (req.query.key !== config.server.invalidateCacheKey) {
9+
if (req.query.key !== config.get('server.invalidateCacheKey')) {
1010
console.error('Invalid cache invalidation key')
1111
apiStatus(res, 'Invalid cache invalidation key', 500)
1212
return
1313
}
1414
console.log(`Clear cache request for [${req.query.tag}]`)
1515
let tags = []
1616
if (req.query.tag === '*') {
17-
tags = config.server.availableCacheTags
17+
tags = config.get('server.availableCacheTags')
1818
} else {
1919
tags = req.query.tag.split(',')
2020
}
2121
const subPromises = []
2222
tags.forEach(tag => {
23-
if (config.server.availableCacheTags.indexOf(tag) >= 0 || config.server.availableCacheTags.find(t => {
23+
if ((config.get('server.availableCacheTags') as [string]).indexOf(tag) >= 0 || (config.get('server.availableCacheTags') as [string]).find(t => {
2424
return tag.indexOf(t) === 0
2525
})) {
2626
subPromises.push(cache.invalidate(tag).then(() => {
@@ -36,9 +36,9 @@ function invalidateCache (req, res) {
3636
apiStatus(res, error, 500)
3737
console.error(error)
3838
})
39-
if (config.server.invalidateCacheForwarding) { // forward invalidate request to the next server in the chain
40-
if (!req.query.forwardedFrom && config.server.invalidateCacheForwardUrl) { // don't forward forwarded requests
41-
request(config.server.invalidateCacheForwardUrl + req.query.tag + '&forwardedFrom=vs', {}, (err, res, body) => {
39+
if (config.get('server.invalidateCacheForwarding')) { // forward invalidate request to the next server in the chain
40+
if (!req.query.forwardedFrom && config.get('server.invalidateCacheForwardUrl')) { // don't forward forwarded requests
41+
request(config.get('server.invalidateCacheForwardUrl') + req.query.tag + '&forwardedFrom=vs', {}, (err, res, body) => {
4242
if (err) { console.error(err); }
4343
try {
4444
if (body && JSON.parse(body).code !== 200) console.log(body);

src/api/order.js renamed to src/api/order.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ export default ({ config, db }) => resource({
4343
console.log(JSON.stringify(incomingOrder))
4444

4545
for (let product of req.body.products) {
46-
let key = config.tax.calculateServerSide ? { priceInclTax: product.priceInclTax } : { price: product.price }
46+
let key: { id?: string, sku?: string, priceInclTax?: number, price?: number } = config.tax.calculateServerSide ? { priceInclTax: product.priceInclTax } : { price: product.price }
4747
if (config.tax.alwaysSyncPlatformPricesOver) {
4848
key.id = product.id
4949
} else {

0 commit comments

Comments
 (0)