Skip to content

Commit 7a424cc

Browse files
authored
Merge pull request #492 from vtex-apps/TIS-339-Autocomplete-routes-on-search-resolver
Add shadow traffic to top-searches, search-suggestions and changed the shadow traffic on autocomplete to 10%
2 parents 640e2c5 + 29db492 commit 7a424cc

File tree

10 files changed

+133
-16
lines changed

10 files changed

+133
-16
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
77

88
## [Unreleased]
99

10+
### Changed
11+
12+
- Send 10% of the production traffic to the new intsch service authough still uses the result from the I/O app. For the routes: autocompleteSearchSuggestions, topSearches and searchSuggestions.
13+
1014
## [1.77.0] - 2025-09-23
1115

1216
### Changed

node/clients/intelligent-search-api.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ export class IntelligentSearchApi
7171
this.locale = locale ?? tenant?.locale
7272
}
7373

74-
public async topSearches() {
74+
public async fetchTopSearches() {
7575
return this.http.get('/top_searches', {
7676
params: {
7777
locale: this.locale,
@@ -87,7 +87,7 @@ export class IntelligentSearchApi
8787
})
8888
}
8989

90-
public async searchSuggestions(params: SearchSuggestionsParams) {
90+
public async fetchSearchSuggestions(params: SearchSuggestionsParams) {
9191
return this.http.get('/search_suggestions', {
9292
params: { ...params, locale: this.locale },
9393
metric: 'searchSuggestions',

node/clients/intsch/index.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@ import {
44
AutocompleteSuggestionsArgs,
55
AutocompleteSuggestionsResponse,
66
IIntelligentSearchClient,
7+
SearchSuggestionsArgs,
8+
SearchSuggestionsResponse,
9+
TopSearchesResponse,
710
} from './types'
811

912
export class Intsch extends JanusClient implements IIntelligentSearchClient {
@@ -30,4 +33,20 @@ export class Intsch extends JanusClient implements IIntelligentSearchClient {
3033
}
3134
)
3235
}
36+
37+
public fetchTopSearches(): Promise<TopSearchesResponse> {
38+
return this.http.get('/api/intelligent-search/v0/top-searches', {
39+
params: { locale: this.locale },
40+
metric: 'topSearches-new',
41+
})
42+
}
43+
44+
public fetchSearchSuggestions(
45+
args: SearchSuggestionsArgs
46+
): Promise<SearchSuggestionsResponse> {
47+
return this.http.get('/api/intelligent-search/v0/search-suggestions', {
48+
params: { query: args.query, locale: this.locale },
49+
metric: 'searchSuggestions-new',
50+
})
51+
}
3352
}

node/clients/intsch/types.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,29 @@ export type AutocompleteSuggestionsResponse = {
1717
}[]
1818
}
1919

20+
export type TopSearchesResponse = {
21+
searches: {
22+
term: string
23+
count: number
24+
}[]
25+
}
26+
27+
export type SearchSuggestionsArgs = {
28+
query: string
29+
}
30+
31+
export type SearchSuggestionsResponse = {
32+
searches: {
33+
term: string
34+
count: number
35+
}[]
36+
}
37+
2038
// eslint-disable-next-line @typescript-eslint/interface-name-prefix
2139
export interface IIntelligentSearchClient {
2240
fetchAutocompleteSuggestions(
2341
args: AutocompleteSuggestionsArgs
2442
): Promise<AutocompleteSuggestionsResponse>
43+
fetchTopSearches(): Promise<TopSearchesResponse>
44+
fetchSearchSuggestions(args: SearchSuggestionsArgs): Promise<SearchSuggestionsResponse>
2545
}

node/index.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,11 @@ export default new Service<Clients, RecorderState, CustomContext>({
6262
concurrency: 10,
6363
timeout: NINE_SECONDS_MS,
6464
},
65+
intsch: {
66+
retries: 0,
67+
concurrency: 10,
68+
timeout: NINE_SECONDS_MS,
69+
},
6570
rewriter: {
6671
timeout: SIX_SECONDS_MS,
6772
},

node/mocks/intelligent-search-api.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,23 @@ export class MockedIntelligentSearchApiClient
1414
args?.fetchAutocompleteSuggestions ?? null
1515
)
1616
}
17+
18+
if (args?.fetchTopSearches instanceof Error) {
19+
this.fetchTopSearches.mockRejectedValue(args.fetchTopSearches)
20+
} else {
21+
this.fetchTopSearches.mockResolvedValue(args?.fetchTopSearches ?? null)
22+
}
23+
24+
if (args?.fetchSearchSuggestions instanceof Error) {
25+
this.fetchSearchSuggestions.mockRejectedValue(args.fetchSearchSuggestions)
26+
} else {
27+
this.fetchSearchSuggestions.mockResolvedValue(
28+
args?.fetchSearchSuggestions ?? null
29+
)
30+
}
1731
}
1832

1933
public fetchAutocompleteSuggestions = jest.fn()
34+
public fetchTopSearches = jest.fn()
35+
public fetchSearchSuggestions = jest.fn()
2036
}

node/mocks/intsch.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import type {
22
IIntelligentSearchClient,
33
AutocompleteSuggestionsResponse,
4+
TopSearchesResponse,
5+
SearchSuggestionsResponse,
46
} from '../clients/intsch/types'
57

68
export class MockedIntschClient implements IIntelligentSearchClient {
@@ -14,11 +16,29 @@ export class MockedIntschClient implements IIntelligentSearchClient {
1416
args?.fetchAutocompleteSuggestions ?? null
1517
)
1618
}
19+
20+
if (args?.fetchTopSearches instanceof Error) {
21+
this.fetchTopSearches.mockRejectedValue(args.fetchTopSearches)
22+
} else {
23+
this.fetchTopSearches.mockResolvedValue(args?.fetchTopSearches ?? null)
24+
}
25+
26+
if (args?.fetchSearchSuggestions instanceof Error) {
27+
this.fetchSearchSuggestions.mockRejectedValue(args.fetchSearchSuggestions)
28+
} else {
29+
this.fetchSearchSuggestions.mockResolvedValue(
30+
args?.fetchSearchSuggestions ?? null
31+
)
32+
}
1733
}
1834

1935
public fetchAutocompleteSuggestions = jest.fn()
36+
public fetchTopSearches = jest.fn()
37+
public fetchSearchSuggestions = jest.fn()
2038
}
2139

2240
export type IntelligentSearchClientArgs = {
2341
fetchAutocompleteSuggestions?: AutocompleteSuggestionsResponse | Error
42+
fetchTopSearches?: TopSearchesResponse | Error
43+
fetchSearchSuggestions?: SearchSuggestionsResponse | Error
2444
}

node/resolvers/search/index.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,11 @@ import {
3333
getShippingOptionsFromSelectedFacets,
3434
validMapAndQuery,
3535
} from './utils'
36-
import { fetchAutocompleteSuggestions } from '../../services/autocomplete'
36+
import {
37+
fetchAutocompleteSuggestions,
38+
fetchTopSearches,
39+
fetchSearchSuggestions
40+
} from '../../services/autocomplete'
3741
interface ProductIndentifier {
3842
field: 'id' | 'slug' | 'ean' | 'reference' | 'sku'
3943
value: string
@@ -725,10 +729,8 @@ export const queries = {
725729
)
726730
return getSearchMetaData(_, compatibilityArgs, ctx)
727731
},
728-
topSearches: async (_: any, __: any, ctx: Context) => {
729-
const { intelligentSearchApi } = ctx.clients
730-
731-
return await intelligentSearchApi.topSearches()
732+
topSearches: (_: any, __: any, ctx: Context) => {
733+
return fetchTopSearches(ctx)
732734
},
733735
autocompleteSearchSuggestions: (
734736
_: any,
@@ -806,8 +808,6 @@ export const queries = {
806808
})
807809
},
808810
searchSuggestions: (_: any, args: { fullText: string }, ctx: Context) => {
809-
const { intelligentSearchApi } = ctx.clients
810-
811-
return intelligentSearchApi.searchSuggestions({ query: args.fullText })
811+
return fetchSearchSuggestions(ctx, args.fullText)
812812
},
813813
}

node/services/autocomplete.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ describe('fetchAutocompleteSuggestions', () => {
9797
query: 'test',
9898
})
9999
expect(ctx.vtex.logger.error).toHaveBeenCalledWith({
100-
message: 'Autocomplete Suggestions: "test": Results differ',
100+
message: 'Autocomplete Suggestions: Results differ',
101101
params: JSON.stringify({ query: 'test' }),
102102
})
103103
expect(response).toEqual(result)

node/services/autocomplete.ts

Lines changed: 38 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,6 @@ import type { Context } from '@vtex/api'
33
import { compareApiResults } from '../utils/compareResults'
44
import type { Clients } from '../clients'
55

6-
/**
7-
* Fetches autocomplete suggestions using the legacy intelligent-search-api
8-
*/
96
export function fetchAutocompleteSuggestions(
107
ctx: Context<Clients>,
118
query: string
@@ -21,10 +18,46 @@ export function fetchAutocompleteSuggestions(
2118
intsch.fetchAutocompleteSuggestions({
2219
query,
2320
}),
24-
ctx.vtex.production ? 1 : 100,
21+
ctx.vtex.production ? 10 : 100,
2522
ctx.vtex.logger,
2623
{
27-
logPrefix: `Autocomplete Suggestions: "${query}"`,
24+
logPrefix: 'Autocomplete Suggestions',
25+
args: { query },
26+
}
27+
)
28+
}
29+
30+
export function fetchTopSearches(ctx: Context<Clients>) {
31+
const { intelligentSearchApi, intsch } = ctx.clients
32+
33+
return compareApiResults(
34+
() => intelligentSearchApi.fetchTopSearches(),
35+
() => intsch.fetchTopSearches(),
36+
ctx.vtex.production ? 10 : 100,
37+
ctx.vtex.logger,
38+
{
39+
logPrefix: 'Top Searches',
40+
args: {},
41+
}
42+
)
43+
}
44+
45+
export function fetchSearchSuggestions(ctx: Context<Clients>, query: string) {
46+
const { intelligentSearchApi, intsch } = ctx.clients
47+
48+
return compareApiResults(
49+
() =>
50+
intelligentSearchApi.fetchSearchSuggestions({
51+
query,
52+
}),
53+
() =>
54+
intsch.fetchSearchSuggestions({
55+
query,
56+
}),
57+
ctx.vtex.production ? 10 : 100,
58+
ctx.vtex.logger,
59+
{
60+
logPrefix: 'Search Suggestions',
2861
args: { query },
2962
}
3063
)

0 commit comments

Comments
 (0)