Skip to content

Commit 7c0b95d

Browse files
[Backport 8.0] Changelog for 8.0 (#1622)
Co-authored-by: Tomas Della Vedova <[email protected]>
1 parent b7b94e2 commit 7c0b95d

File tree

1 file changed

+307
-0
lines changed

1 file changed

+307
-0
lines changed

docs/changelog.asciidoc

Lines changed: 307 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,307 @@
1+
[[changelog-client]]
2+
== Release notes
3+
4+
[discrete]
5+
=== 8.0.0
6+
7+
[discrete]
8+
==== Features
9+
10+
[discrete]
11+
[discrete]
12+
===== Support for Elasticsearch `v8.0`
13+
14+
You can find all the API changes
15+
https://www.elastic.co/guide/en/elasticsearch/reference/8.0/release-notes-8.0.0.html[here].
16+
17+
[discrete]
18+
===== Drop old typescript definitions
19+
20+
*Breaking: Yes* | *Migration effort: Medium*
21+
22+
The current TypeScript definitions will be removed from the client, and the new definitions, which contain request and response definitions as well will be shipped by default.
23+
24+
[discrete]
25+
===== Drop callback-style API
26+
27+
*Breaking: Yes* | *Migration effort: Large*
28+
29+
Maintaining both API styles is not a problem per se, but it makes error handling more convoluted due to async stack traces.
30+
Moving to a full-promise API will solve this issue.
31+
32+
[source,js]
33+
----
34+
// callback-style api
35+
client.search({ params }, { options }, (err, result) => {
36+
console.log(err || result)
37+
})
38+
39+
// promise-style api
40+
client.search({ params }, { options })
41+
.then(console.log)
42+
.catch(console.log)
43+
44+
// async-style (sugar syntax on top of promises)
45+
const response = await client.search({ params }, { options })
46+
console.log(response)
47+
----
48+
49+
If you are already using the promise-style API, this won't be a breaking change for you.
50+
51+
[discrete]
52+
===== Remove the current abort API and use the new AbortController standard
53+
54+
*Breaking: Yes* | *Migration effort: Small*
55+
56+
The old abort API makes sense for callbacks but it's annoying to use with promises
57+
58+
[source,js]
59+
----
60+
// callback-style api
61+
const request = client.search({ params }, { options }, (err, result) => {
62+
console.log(err) // RequestAbortedError
63+
})
64+
65+
request.abort()
66+
67+
// promise-style api
68+
const promise = client.search({ params }, { options })
69+
70+
promise
71+
.then(console.log)
72+
.catch(console.log) // RequestAbortedError
73+
74+
promise.abort()
75+
----
76+
77+
Node v12 has added the standard https://nodejs.org/api/globals.html#globals_class_abortcontroller[`AbortController`] API which is designed to work well with both callbacks and promises.
78+
[source,js]
79+
----
80+
const ac = new AbortController()
81+
client.search({ params }, { signal: ac.signal })
82+
.then(console.log)
83+
.catch(console.log) // RequestAbortedError
84+
85+
ac.abort()
86+
----
87+
88+
[discrete]
89+
===== Remove the body key from the request
90+
91+
*Breaking: Yes* | *Migration effort: Small*
92+
93+
Thanks to the new types we are developing now we know exactly where a parameter should go.
94+
The client API leaks HTTP-related notions in many places, and removing them would definitely improve the DX.
95+
96+
This could be a rather big breaking change, so a double solution could be used during the 8.x lifecycle. (accepting body keys without them being wrapped in the body as well as the current solution).
97+
98+
[source,js]
99+
----
100+
// from
101+
const response = await client.search({
102+
index: 'test',
103+
body: {
104+
query: {
105+
match_all: {}
106+
}
107+
}
108+
})
109+
110+
// to
111+
const response = await client.search({
112+
index: 'test',
113+
query: {
114+
match_all: {}
115+
}
116+
})
117+
----
118+
119+
[discrete]
120+
===== Migrate to new separate transport
121+
122+
*Breaking: Yes* | *Migration effort: Small to none*
123+
124+
The separated transport has been rewritten in TypeScript and has already dropped the callback style API.
125+
Given that now is separated, most of the Elasticsearch specific concepts have been removed, and the client will likely need to extend parts of it for reintroducing them.
126+
If you weren't extending the internals of the client, this won't be a breaking change for you.
127+
128+
[discrete]
129+
===== The returned value of API calls is the body and not the HTTP related keys
130+
131+
*Breaking: Yes* | *Migration effort: Small*
132+
133+
The client API leaks HTTP-related notions in many places, and removing them would definitely improve the DX.
134+
The client will expose a new request-specific option to still get the full response details.
135+
136+
[source,js]
137+
----
138+
// from
139+
const response = await client.search({
140+
index: 'test',
141+
body: {
142+
query: {
143+
match_all: {}
144+
}
145+
}
146+
})
147+
console.log(response) // { body: SearchResponse, statusCode: number, headers: object, warnings: array }
148+
149+
// to
150+
const response = await client.search({
151+
index: 'test',
152+
query: {
153+
match_all: {}
154+
}
155+
})
156+
console.log(response) // SearchResponse
157+
158+
// with a bit of TypeScript and JavaScript magic...
159+
const response = await client.search({
160+
index: 'test',
161+
query: {
162+
match_all: {}
163+
}
164+
}, {
165+
meta: true
166+
})
167+
console.log(response) // { body: SearchResponse, statusCode: number, headers: object, warnings: array }
168+
----
169+
170+
[discrete]
171+
===== Use a weighted connection pool
172+
173+
*Breaking: Yes* | *Migration effort: Small to none*
174+
175+
Move from the current cluster connection pool to a weight-based implementation.
176+
This new implementation offers better performances and runs less code in the background, the old connection pool can still be used.
177+
If you weren't extending the internals of the client, this won't be a breaking change for you.
178+
179+
[discrete]
180+
===== Migrate to the "undici" http client
181+
182+
*Breaking: Yes* | *Migration effort: Small to none*
183+
184+
By default, the HTTP client will no longer be the default Node.js HTTP client, but https://github.com/nodejs/undici[undici] instead.
185+
Undici is a brand new HTTP client written from scratch, it offers vastly improved performances and has better support for promises.
186+
Furthermore, it offers comprehensive and predictable error handling. The old HTTP client can still be used.
187+
If you weren't extending the internals of the client, this won't be a breaking change for you.
188+
189+
[discrete]
190+
===== Drop support for old camelCased keys
191+
192+
*Breaking: Yes* | *Migration effort: Medium*
193+
194+
Currently, every path or query parameter could be expressed in both `snake_case` and `camelCase`. Internally the client will convert everything to `snake_case`.
195+
This was done in an effort to reduce the friction of migrating from the legacy to the new client, but now it no longer makes sense.
196+
If you are already using `snake_case` keys, this won't be a breaking change for you.
197+
198+
[discrete]
199+
===== Rename `ssl` option to `tls`
200+
201+
*Breaking: Yes* | *Migration effort: Small*
202+
203+
People usually refers to this as `tls`, furthermore, internally we use the tls API and Node.js refers to it as tls everywhere.
204+
[source,js]
205+
----
206+
// before
207+
const client = new Client({
208+
node: 'https://localhost:9200',
209+
ssl: {
210+
rejectUnauthorized: false
211+
}
212+
})
213+
214+
// after
215+
const client = new Client({
216+
node: 'https://localhost:9200',
217+
tls: {
218+
rejectUnauthorized: false
219+
}
220+
})
221+
----
222+
223+
[discrete]
224+
===== Remove prototype poisoning protection
225+
226+
*Breaking: Yes* | *Migration effort: Small*
227+
228+
Prototype poisoning protection is very useful, but it can cause performances issues with big payloads.
229+
In v8 it will be removed, and the documentation will show how to add it back with a custom serializer.
230+
231+
[discrete]
232+
===== Remove client extensions API
233+
234+
*Breaking: Yes* | *Migration effort: Large*
235+
236+
Nowadays the client support the entire Elasticsearch API, and the `transport.request` method can be used if necessary. The client extensions API have no reason to exist.
237+
[source,js]
238+
----
239+
client.extend('utility.index', ({ makeRequest }) => {
240+
return function _index (params, options) {
241+
// your code
242+
}
243+
})
244+
245+
client.utility.index(...)
246+
----
247+
248+
If you weren't using client extensions, this won't be a breaking change for you.
249+
250+
[discrete]
251+
===== Move to TypeScript
252+
253+
*Breaking: No* | *Migration effort: None*
254+
255+
The new separated transport is already written in TypeScript, and it makes sense that the client v8 will be fully written in TypeScript as well.
256+
257+
[discrete]
258+
===== Move from emitter-like interface to a diagnostic method
259+
260+
*Breaking: Yes* | *Migration effort: Small*
261+
262+
Currently, the client offers a subset of methods of the `EventEmitter` class, v8 will ship with a `diagnostic` property which will be a proper event emitter.
263+
[source,js]
264+
----
265+
// from
266+
client.on('request', console.log)
267+
268+
// to
269+
client.diagnostic.on('request', console.log)
270+
----
271+
272+
[discrete]
273+
===== Remove username & password properties from Cloud configuration
274+
275+
*Breaking: Yes* | *Migration effort: Small*
276+
277+
The Cloud configuration does not support ApiKey and Bearer auth, while the `auth` options does.
278+
There is no need to keep the legacy basic auth support in the cloud configuration.
279+
[source,js]
280+
----
281+
// before
282+
const client = new Client({
283+
cloud: {
284+
id: '<cloud-id>',
285+
username: 'elastic',
286+
password: 'changeme'
287+
}
288+
})
289+
290+
// after
291+
const client = new Client({
292+
cloud: {
293+
id: '<cloud-id>'
294+
},
295+
auth: {
296+
username: 'elastic',
297+
password: 'changeme'
298+
}
299+
})
300+
----
301+
302+
If you are already passing the basic auth options in the `auth` configuration, this won't be a breaking change for you.
303+
304+
[discrete]
305+
===== Calling `client.close` will reject new requests
306+
307+
Once you call `client.close` every new request after that will be rejected with a `NoLivingConnectionsError`. In-flight requests will be executed normally unless an in-flight request requires a retry, in which case it will be rejected.

0 commit comments

Comments
 (0)