Change document search endpoint to post (#138851) (#138880)

Also stringify the query while passing to the search api.

(cherry picked from commit 4bc142f4a3)

Co-authored-by: Efe Gürkan YALAMAN <efeguerkan.yalaman@elastic.co>
This commit is contained in:
Kibana Machine 2022-08-16 06:30:40 -04:00 committed by GitHub
parent fb0e158a9f
commit 4ec184361f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 47 additions and 72 deletions

View file

@ -19,7 +19,7 @@ describe('SearchDocumentsApiLogic', () => {
describe('searchDocuments', () => {
it('calls correct api', async () => {
const promise = Promise.resolve('result');
http.get.mockReturnValue(promise);
http.post.mockReturnValue(promise);
const result = searchDocuments({
indexName: 'indexName',
pagination: {
@ -28,15 +28,18 @@ describe('SearchDocumentsApiLogic', () => {
},
});
await nextTick();
expect(http.get).toHaveBeenCalledWith(
expect(http.post).toHaveBeenCalledWith(
'/internal/enterprise_search/indices/indexName/search',
{ query: { page: 0, size: 10 } }
{
body: JSON.stringify({}),
query: { page: 0, size: 10 },
}
);
await expect(result).resolves.toEqual('result');
});
it('calls correct api with query set', async () => {
const promise = Promise.resolve('result');
http.get.mockReturnValue(promise);
http.post.mockReturnValue(promise);
const result = searchDocuments({
indexName: 'düsseldorf',
pagination: {
@ -46,15 +49,20 @@ describe('SearchDocumentsApiLogic', () => {
query: 'abcd',
});
await nextTick();
expect(http.get).toHaveBeenCalledWith(
'/internal/enterprise_search/indices/d%C3%BCsseldorf/search/abcd',
{ query: { page: 0, size: 10 } }
expect(http.post).toHaveBeenCalledWith(
'/internal/enterprise_search/indices/d%C3%BCsseldorf/search',
{
body: JSON.stringify({
searchQuery: 'abcd',
}),
query: { page: 0, size: 10 },
}
);
await expect(result).resolves.toEqual('result');
});
it('calls with correct pageSize with docsPerPage set', async () => {
const promise = Promise.resolve('result');
http.get.mockReturnValue(promise);
http.post.mockReturnValue(promise);
const result = searchDocuments({
docsPerPage: 25,
indexName: 'indexName',
@ -64,9 +72,12 @@ describe('SearchDocumentsApiLogic', () => {
},
});
await nextTick();
expect(http.get).toHaveBeenCalledWith(
expect(http.post).toHaveBeenCalledWith(
'/internal/enterprise_search/indices/indexName/search',
{ query: { page: 0, size: 25 } }
{
body: JSON.stringify({}),
query: { page: 0, size: 25 },
}
);
await expect(result).resolves.toEqual('result');
});

View file

@ -24,15 +24,16 @@ export const searchDocuments = async ({
query?: string;
}) => {
const newIndexName = encodeURIComponent(indexName);
const route = `/internal/enterprise_search/indices/${newIndexName}/search${
searchQuery ? `/${searchQuery}` : ''
}`;
const route = `/internal/enterprise_search/indices/${newIndexName}/search`;
const query = {
page: pagination.pageIndex,
size: docsPerPage || pagination.pageSize,
};
return await HttpLogic.values.http.get<{ meta: Meta; results: SearchResponseBody }>(route, {
return await HttpLogic.values.http.post<{ meta: Meta; results: SearchResponseBody }>(route, {
body: JSON.stringify({
searchQuery,
}),
query,
});
};

View file

@ -87,7 +87,7 @@ describe('fetchSearchResults lib function', () => {
expect(mockClient.asCurrentUser.search).toHaveBeenCalledWith({
from: DEFAULT_FROM_VALUE,
index: indexName,
q: query,
q: JSON.stringify(query),
size: ENTERPRISE_SEARCH_DOCUMENTS_DEFAULT_DOC_COUNT,
});
});
@ -120,7 +120,7 @@ describe('fetchSearchResults lib function', () => {
expect(mockClient.asCurrentUser.search).toHaveBeenCalledWith({
from: DEFAULT_FROM_VALUE,
index: indexName,
q: query,
q: JSON.stringify(query),
size: ENTERPRISE_SEARCH_DOCUMENTS_DEFAULT_DOC_COUNT,
});
});

View file

@ -21,7 +21,7 @@ export const fetchSearchResults = async (
from,
index: indexName,
size,
...(!!query ? { q: query } : {}),
...(!!query ? { q: JSON.stringify(query) } : {}),
});
return results;
};

View file

@ -27,8 +27,8 @@ describe('Elasticsearch Search', () => {
mockRouter = new MockRouter({
context,
method: 'get',
path: '/internal/enterprise_search/indices/{index_name}/search/{query}',
method: 'post',
path: '/internal/enterprise_search/indices/{index_name}/search',
});
registerSearchRoute({
@ -37,14 +37,9 @@ describe('Elasticsearch Search', () => {
});
});
describe('GET /internal/enterprise_search/indices/{index_name}/search/{query}', () => {
describe('POST /internal/enterprise_search/indices/{index_name}/search with query on request body', () => {
it('fails validation without index_name', () => {
const request = { params: { query: 'banana' } };
mockRouter.shouldThrow(request);
});
it('fails validation without query', () => {
const request = { params: { index_name: 'search-banana' } };
const request = { body: { searchQuery: '' }, params: {} };
mockRouter.shouldThrow(request);
});
@ -73,7 +68,10 @@ describe('Elasticsearch Search', () => {
});
await mockRouter.callRoute({
params: { index_name: 'search-index-name', query: 'banana' },
body: {
searchQuery: 'banana',
},
params: { index_name: 'search-index-name' },
});
expect(fetchSearchResults).toHaveBeenCalledWith(
@ -102,7 +100,7 @@ describe('Elasticsearch Search', () => {
});
});
describe('GET /internal/enterprise_search/indices/{index_name}/search', () => {
describe('POST /internal/enterprise_search/indices/{index_name}/search', () => {
let mockRouterNoQuery: MockRouter;
beforeEach(() => {
const context = {
@ -111,7 +109,7 @@ describe('Elasticsearch Search', () => {
mockRouterNoQuery = new MockRouter({
context,
method: 'get',
method: 'post',
path: '/internal/enterprise_search/indices/{index_name}/search',
});

View file

@ -37,10 +37,15 @@ const calculateMeta = (searchResults: SearchResponseBody, page: number, size: nu
};
export function registerSearchRoute({ router, log }: RouteDependencies) {
router.get(
router.post(
{
path: '/internal/enterprise_search/indices/{index_name}/search',
validate: {
body: schema.object({
searchQuery: schema.string({
defaultValue: '',
}),
}),
params: schema.object({
index_name: schema.string(),
}),
@ -55,54 +60,14 @@ export function registerSearchRoute({ router, log }: RouteDependencies) {
},
elasticsearchErrorHandler(log, async (context, request, response) => {
const indexName = decodeURIComponent(request.params.index_name);
const searchQuery = request.body.searchQuery;
const { client } = (await context.core).elasticsearch;
const { page = 0, size = ENTERPRISE_SEARCH_DOCUMENTS_DEFAULT_DOC_COUNT } = request.query;
const from = page * size;
const searchResults: SearchResponseBody = await fetchSearchResults(
client,
indexName,
'',
from,
size
);
return response.ok({
body: {
meta: calculateMeta(searchResults, page, size),
results: searchResults,
},
headers: { 'content-type': 'application/json' },
});
})
);
router.get(
{
path: '/internal/enterprise_search/indices/{index_name}/search/{query}',
validate: {
params: schema.object({
index_name: schema.string(),
query: schema.string(),
}),
query: schema.object({
page: schema.number({ defaultValue: 0, min: 0 }),
size: schema.number({
defaultValue: ENTERPRISE_SEARCH_DOCUMENTS_DEFAULT_DOC_COUNT,
min: 0,
}),
}),
},
},
elasticsearchErrorHandler(log, async (context, request, response) => {
const indexName = decodeURIComponent(request.params.index_name);
const { client } = (await context.core).elasticsearch;
const { page = 0, size = ENTERPRISE_SEARCH_DOCUMENTS_DEFAULT_DOC_COUNT } = request.query;
const from = page * size;
const searchResults = await fetchSearchResults(
client,
indexName,
request.params.query,
searchQuery,
from,
size
);