-
Notifications
You must be signed in to change notification settings - Fork 727
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
body
removal causes 400 - illegal_argument_exception
#2584
Comments
Just want to highlight the use case where this surfaced: Here Kibana makes a simulate index template request to retrieve the mappings that an index template would apply if a data stream write index was rolled over. It then uses the mappings from the response to also apply these mappings to existing backing indices (presumably to synchronise the mappings?). Since the simulate index template request responded with While it would be a risky and breaking change to Elasticsearch-js, it seems like defaulting to passing unknown properties in the body would preferably over passing them as query params. This would however break any consumers of Elasticsearch-js that are using query params not in the spec or belonging to a custom plugin (related elastic/elasticsearch-py#2181) |
I do agree that passing unknowns to the body makes more sense than passing as query params. The main concern is, as you said, breaking any existing code that works on the assumption that unknown params will end up in the querystring. My only other concern with using the body as the catch-all place for unknown params is that there are many requests that do not accept a JSON body. In those cases, query params probably are the better choice. It might be possible to update the code generator to be able to choose the ideal catch-all for both of these cases, but I'm not confident I'd have something stable in time for 9.0. I can look into it next week but it will be a tight squeeze. @rudolf @afharo would making this change introduce even more last-minute pain for Kibana, or do you think it will be a smooth transition? If it's painful, maybe holding off is the better choice. |
elastic/kibana#208776 proves that not doing this change is blocking Kibana from removing all WDYT? |
Making a spec change like this is a discussion that would need to happen in the spec repo. Because all request types are derived from the spec, for all language clients, that change has to be something that will be compatible with all dynamic and static clients work.
Which change? Adding |
I'm going to work on changing the catch-all from querystring to body (except for APIs that don't accept a body) soon and get it published in the next 9.0.0 alpha. |
## 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 (elastic/elasticsearch-js#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 [email protected] 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 [email protected] 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 <[email protected]>
As of #2636 the param logic changes to:
The first two steps are identical to 8.x. The last three steps replace the logic that put all unrecognized params in the querystring. The change also updates each API function to only instantiate its arrays of accepted body/path/query param names once per client instance rather than during every function call, by moving the array values up to the constructor or module, depending on which is available. Hopefully that introduces a small performance/memory improvement. I'm going to merge that PR today and publish |
## Summary Updating the ES client to 9.0. Resolves elastic#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 (elastic/elasticsearch-js#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 [email protected] 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 [email protected] 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 <[email protected]>
Regression report
In Kibana, we're migrating to stop using the deprecated
body
key. An example is elastic/kibana#204882.However, some of our tests started failing with the following error:
We managed to ship this because the code tries to update some existing mappings by GET the existing ones and PUT the full updated object.
_data_stream_timestamp
was automatically populated by ES and returned in GET request.The old logic using the
body
param works because it forces the client to ship that parameter in the body of the request. However, after removing thebody
param, the client sent that property as a query parameter, leading to ES validation issues as this property is only accepted in the body.Last working version
8.16.0
To reproduce
Try to update the mappings of an existing data stream by GET-ing the mappings first, adding the new field in the mappings, and PUT-ing the resulting object.
Expected behavior
The request is successful.
Node.js version
v20.18.2
TypeScript version
5.1.6
Elasticsearch client version
@elastic/[email protected] - @elastic/[email protected]
Elasticsearch server version
9.0.0-SNAPSHOT
Operating system
No response
Any other relevant environment information.
No response
The text was updated successfully, but these errors were encountered: