kibana/examples/search_examples/server/routes/server_search_route.ts
Alejandro Fernández Haro 52ab19db2d
Upgrade ES client to 9.0.0-alpha.3 (#208776)
## Summary

Updating the ES client to 9.0. 

Resolves #116102

## What changes?

**Breaking change**: `body` has been removed.

Most of the changes are about bringing all the content inside the body
as a root attribute to the API params:

```diff
const response = await client.search({
  index: 'test',
-  body: {
    query: {
      match_all: {}
    }
-  }
})
```

For this reason, enabling the "Hide whitespace changes" option when
reviewing is recommended.

Some exceptions to this rule:

* Bulk APIs replace the `body` array with `operations` array (direct
replacement)
* Index Put Settings API replace `body` array with `settings` (direct
replacement)
* Msearch replaces the `body` array with `searches` array (direct
replacement)
* Document Index API replaces `body` with `document` (direct
replacement)
* Create Repository replaces `body` with `repository` (direct
replacement)

Because of a known issue in the client
(https://github.com/elastic/elasticsearch-js/issues/2584), there's still
an escape hatch to send data in the body in case the specific use case
requires it via `// @ts-expect-error elasticsearch@9.0.0
https://github.com/elastic/elasticsearch-js/issues/2584`, but it
shouldn't be abused because we lose types. In this PR we've used it in
those scenarios where we reuse the response of a GET as the body of a
PUT/POST.

### Other changes

* `estypes` can be imported from the root of the library as `import type
{ estypes } from '@elastic/elasticsearch';`
* `estypesWithBody` have been removed
* `requestTimeout`'s 30s default has been removed in the client. This PR
explicitly adds the setting in all client usages.


### Identify risks

- [x] The client places unknown properties as querystring, risking body
params leaking there, and causing 400 errors from ES => Solved by
forcing `body` usage there via `// @ts-expect-error elasticsearch@9.0.0
https://github.com/elastic/elasticsearch-js/issues/2584`. The next
version of the client will address this.
- [x] We need to run the MKI tests to make sure that we're not breaking
anything there =>
https://elastic.slack.com/archives/C04HT4P1YS3/p1739528112482629?thread_ts=1739480136.231439&cid=C04HT4P1YS3

---------

Co-authored-by: Gloria Hornero <gloria.hornero@elastic.co>
2025-02-25 14:37:23 +00:00

76 lines
2.4 KiB
TypeScript

/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the "Elastic License
* 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side
* Public License v 1"; you may not use this file except in compliance with, at
* your election, the "Elastic License 2.0", the "GNU Affero General Public
* License v3.0 only", or the "Server Side Public License, v 1".
*/
import { Observable } from 'rxjs';
import type { IEsSearchRequest, IEsSearchResponse } from '@kbn/search-types';
import { schema } from '@kbn/config-schema';
import type { DataRequestHandlerContext } from '@kbn/data-plugin/server';
import type { IRouter } from '@kbn/core/server';
import { SERVER_SEARCH_ROUTE_PATH } from '../../common';
export function registerServerSearchRoute(router: IRouter<DataRequestHandlerContext>) {
router.get(
{
path: SERVER_SEARCH_ROUTE_PATH,
validate: {
query: schema.object({
index: schema.maybe(schema.string()),
field: schema.maybe(schema.string()),
}),
},
},
async (context, request, response) => {
const { index, field } = request.query;
// User may abort the request without waiting for the results
// we need to handle this scenario by aborting underlying server requests
const abortSignal = getRequestAbortedSignal(request.events.aborted$);
try {
const search = await context.search;
const res = await search
.search(
{
params: {
index,
aggs: {
'1': {
avg: {
field,
},
},
},
},
} as IEsSearchRequest,
{ abortSignal }
)
.toPromise();
return response.ok({
body: {
aggs: (res as IEsSearchResponse).rawResponse.aggregations,
},
});
} catch (e) {
return response.customError({
statusCode: e.statusCode ?? 500,
body: {
message: e.message,
},
});
}
}
);
}
function getRequestAbortedSignal(aborted$: Observable<void>): AbortSignal {
const controller = new AbortController();
aborted$.subscribe(() => controller.abort());
return controller.signal;
}