[DOCS] Adds Integrations section to Node.JS docs (#1407)
Co-authored-by: Tomas Della Vedova <delvedor@users.noreply.github.com>
This commit is contained in:
committed by
GitHub
parent
22ece32c5c
commit
36eaed6466
@ -4,45 +4,11 @@
|
|||||||
If you need to customize the client behavior heavily, you are in the right
|
If you need to customize the client behavior heavily, you are in the right
|
||||||
place! The client enables you to customize the following internals:
|
place! The client enables you to customize the following internals:
|
||||||
|
|
||||||
* `Transport` class
|
|
||||||
* `ConnectionPool` class
|
* `ConnectionPool` class
|
||||||
* `Connection` class
|
* `Connection` class
|
||||||
* `Serializer` class
|
* `Serializer` class
|
||||||
|
|
||||||
|
NOTE: For information about the `Transport` class, refer to <<transport>>.
|
||||||
[discrete]
|
|
||||||
==== `Transport`
|
|
||||||
|
|
||||||
This class is responsible for performing the request to {es} and handling
|
|
||||||
errors, it also handles the sniffing.
|
|
||||||
|
|
||||||
[source,js]
|
|
||||||
----
|
|
||||||
const { Client, Transport } = require('@elastic/elasticsearch')
|
|
||||||
|
|
||||||
class MyTransport extends Transport {
|
|
||||||
request (params, options, callback) {
|
|
||||||
// your code
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const client = new Client({
|
|
||||||
Transport: MyTransport
|
|
||||||
})
|
|
||||||
----
|
|
||||||
|
|
||||||
Sometimes you need to inject a small snippet of your code and then continue to
|
|
||||||
use the usual client code. In such cases, call `super.method`:
|
|
||||||
|
|
||||||
[source,js]
|
|
||||||
----
|
|
||||||
class MyTransport extends Transport {
|
|
||||||
request (params, options, callback) {
|
|
||||||
// your code
|
|
||||||
return super.request(params, options, callback)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
----
|
|
||||||
|
|
||||||
|
|
||||||
[discrete]
|
[discrete]
|
||||||
|
|||||||
@ -9,3 +9,4 @@ section, you can see the possible options that you can use to configure it.
|
|||||||
* <<advanced-config>>
|
* <<advanced-config>>
|
||||||
* <<child>>
|
* <<child>>
|
||||||
* <<extend>>
|
* <<extend>>
|
||||||
|
* <<client-testing>>
|
||||||
|
|||||||
@ -11,10 +11,12 @@ include::basic-config.asciidoc[]
|
|||||||
include::advanced-config.asciidoc[]
|
include::advanced-config.asciidoc[]
|
||||||
include::child.asciidoc[]
|
include::child.asciidoc[]
|
||||||
include::extend.asciidoc[]
|
include::extend.asciidoc[]
|
||||||
|
include::testing.asciidoc[]
|
||||||
|
include::integrations.asciidoc[]
|
||||||
|
include::observability.asciidoc[]
|
||||||
|
include::transport.asciidoc[]
|
||||||
|
include::typescript.asciidoc[]
|
||||||
include::reference.asciidoc[]
|
include::reference.asciidoc[]
|
||||||
include::breaking-changes.asciidoc[]
|
include::breaking-changes.asciidoc[]
|
||||||
include::observability.asciidoc[]
|
|
||||||
include::helpers.asciidoc[]
|
include::helpers.asciidoc[]
|
||||||
include::typescript.asciidoc[]
|
|
||||||
include::testing.asciidoc[]
|
|
||||||
include::examples/index.asciidoc[]
|
include::examples/index.asciidoc[]
|
||||||
|
|||||||
8
docs/integrations.asciidoc
Normal file
8
docs/integrations.asciidoc
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
[[integrations]]
|
||||||
|
== Integrations
|
||||||
|
|
||||||
|
The Client offers the following integration options for you:
|
||||||
|
|
||||||
|
* <<observability>>
|
||||||
|
* <<transport>>
|
||||||
|
* <<typescript>>
|
||||||
@ -1,19 +1,19 @@
|
|||||||
[[observability]]
|
[[observability]]
|
||||||
== Observability
|
=== Observability
|
||||||
|
|
||||||
The client does not provide a default logger, but instead it offers an event
|
The client does not provide a default logger, but instead it offers an event
|
||||||
emitter interfaces to hook into internal events, such as `request` and
|
emitter interfaces to hook into internal events, such as `request` and
|
||||||
`response`.
|
`response`.
|
||||||
|
|
||||||
Correlating those events can be quite hard, especially if your applications have
|
Correlating those events can be hard, especially if your applications have a
|
||||||
a large codebase with many events happening at the same time.
|
large codebase with many events happening at the same time.
|
||||||
|
|
||||||
To help you with this, the client offers you a correlation id system and other
|
To help you with this, the client offers you a correlation id system and other
|
||||||
features. Let's see them in action.
|
features. Let's see them in action.
|
||||||
|
|
||||||
|
|
||||||
[discrete]
|
[discrete]
|
||||||
=== Events
|
==== Events
|
||||||
|
|
||||||
The client is an event emitter, this means that you can listen for its event and
|
The client is an event emitter, this means that you can listen for its event and
|
||||||
add additional logic to your code, without need to change the client internals
|
add additional logic to your code, without need to change the client internals
|
||||||
@ -105,7 +105,8 @@ client.on('resurrect', (err, result) => {
|
|||||||
|
|
||||||
|===
|
|===
|
||||||
|
|
||||||
The values of `result` in `serialization`, `request`, `deserialization`, `response` and `sniff` will be:
|
The values of `result` in `serialization`, `request`, `deserialization`,
|
||||||
|
`response` and `sniff` are:
|
||||||
|
|
||||||
[source,ts]
|
[source,ts]
|
||||||
----
|
----
|
||||||
@ -132,7 +133,7 @@ meta: {
|
|||||||
----
|
----
|
||||||
|
|
||||||
|
|
||||||
While the `result` value in `resurrect` will be:
|
While the `result` value in `resurrect` is:
|
||||||
|
|
||||||
[source,ts]
|
[source,ts]
|
||||||
----
|
----
|
||||||
@ -146,10 +147,13 @@ request: {
|
|||||||
----
|
----
|
||||||
|
|
||||||
[discrete]
|
[discrete]
|
||||||
==== Events order
|
===== Events order
|
||||||
|
|
||||||
The event order is described in the following graph, in some edge cases, the order is not guaranteed.
|
The event order is described in the following graph, in some edge cases, the
|
||||||
You can find in https://github.com/elastic/elasticsearch-js/blob/master/test/acceptance/events-order.test.js[`test/acceptance/events-order.test.js`] how the order changes based on the situation.
|
order is not guaranteed.
|
||||||
|
You can find in
|
||||||
|
https://github.com/elastic/elasticsearch-js/blob/master/test/acceptance/events-order.test.js[`test/acceptance/events-order.test.js`]
|
||||||
|
how the order changes based on the situation.
|
||||||
|
|
||||||
[source]
|
[source]
|
||||||
----
|
----
|
||||||
@ -170,11 +174,11 @@ serialization
|
|||||||
|
|
||||||
|
|
||||||
[discrete]
|
[discrete]
|
||||||
=== Correlation id
|
==== Correlation id
|
||||||
|
|
||||||
Correlating events can be quite hard, especially if there are many events at the
|
Correlating events can be hard, especially if there are many events at the same
|
||||||
same time. The client offers you an automatic (and configurable) system to help
|
time. The client offers you an automatic (and configurable) system to help you
|
||||||
you handle this problem.
|
handle this problem.
|
||||||
|
|
||||||
[source,js]
|
[source,js]
|
||||||
----
|
----
|
||||||
@ -204,8 +208,8 @@ client.search({
|
|||||||
----
|
----
|
||||||
|
|
||||||
|
|
||||||
By default the id is an incremental integer, but you can easily configure that
|
By default the id is an incremental integer, but you can configure it with the
|
||||||
with the `generateRequestId` option:
|
`generateRequestId` option:
|
||||||
|
|
||||||
[source,js]
|
[source,js]
|
||||||
----
|
----
|
||||||
@ -238,7 +242,7 @@ client.search({
|
|||||||
|
|
||||||
|
|
||||||
[discrete]
|
[discrete]
|
||||||
=== Context object
|
==== Context object
|
||||||
|
|
||||||
Sometimes, you might need to make some custom data available in your events, you
|
Sometimes, you might need to make some custom data available in your events, you
|
||||||
can do that via the `context` option of a request:
|
can do that via the `context` option of a request:
|
||||||
@ -275,8 +279,8 @@ client.search({
|
|||||||
----
|
----
|
||||||
|
|
||||||
The context object can also be configured as a global option in the client
|
The context object can also be configured as a global option in the client
|
||||||
configuration. If you provide both, the two context object will be shallow merged,
|
configuration. If you provide both, the two context objects will be shallow
|
||||||
and the API level object will take precedece.
|
merged, and the API level object will take precedence.
|
||||||
|
|
||||||
[source,js]
|
[source,js]
|
||||||
----
|
----
|
||||||
@ -314,12 +318,12 @@ client.search({
|
|||||||
|
|
||||||
|
|
||||||
[discrete]
|
[discrete]
|
||||||
=== Client name
|
==== Client name
|
||||||
|
|
||||||
If you are using multiple instances of the client or if you are using multiple
|
If you are using multiple instances of the client or if you are using multiple
|
||||||
child clients _(which is the recommended way to have multiple instances of the
|
child clients _(which is the recommended way to have multiple instances of the
|
||||||
client)_, you might need to recognize which client you are using. The `name`
|
client)_, you might need to recognize which client you are using. The `name`
|
||||||
options will help you in this regard.
|
options help you in this regard.
|
||||||
|
|
||||||
[source,js]
|
[source,js]
|
||||||
----
|
----
|
||||||
@ -368,13 +372,13 @@ child.search({
|
|||||||
|
|
||||||
|
|
||||||
[discrete]
|
[discrete]
|
||||||
=== X-Opaque-Id support
|
==== X-Opaque-Id support
|
||||||
|
|
||||||
To improve the overall observability, the client offers an easy way to configure
|
To improve observability, the client offers an easy way to configure the
|
||||||
the `X-Opaque-Id` header. If you set the `X-Opaque-Id` in a specific request,
|
`X-Opaque-Id` header. If you set the `X-Opaque-Id` in a specific request, this
|
||||||
this will allow you to discover this identifier in the
|
allows you to discover this identifier in the
|
||||||
https://www.elastic.co/guide/en/elasticsearch/reference/master/logging.html#deprecation-logging[deprecation logs],
|
https://www.elastic.co/guide/en/elasticsearch/reference/master/logging.html#deprecation-logging[deprecation logs],
|
||||||
help you with https://www.elastic.co/guide/en/elasticsearch/reference/master/index-modules-slowlog.html#_identifying_search_slow_log_origin[identifying search slow log origin]
|
helps you with https://www.elastic.co/guide/en/elasticsearch/reference/master/index-modules-slowlog.html#_identifying_search_slow_log_origin[identifying search slow log origin]
|
||||||
as well as https://www.elastic.co/guide/en/elasticsearch/reference/master/tasks.html#_identifying_running_tasks[identifying running tasks].
|
as well as https://www.elastic.co/guide/en/elasticsearch/reference/master/tasks.html#_identifying_running_tasks[identifying running tasks].
|
||||||
|
|
||||||
The `X-Opaque-Id` should be configured in each request, for doing that you can
|
The `X-Opaque-Id` should be configured in each request, for doing that you can
|
||||||
|
|||||||
@ -1,56 +1,58 @@
|
|||||||
[[client-testing]]
|
[[client-testing]]
|
||||||
== Testing
|
=== Testing
|
||||||
|
|
||||||
Testing is one of the most important parts of developing an application.
|
Testing is one of the most important parts of developing an application.
|
||||||
The client is very flexible when it comes to testing and is compatible with
|
The client is very flexible when it comes to testing and is compatible with
|
||||||
most testing frameworks (such as https://www.npmjs.com/package/ava[`ava`],
|
most testing frameworks (such as https://www.npmjs.com/package/ava[`ava`],
|
||||||
which is used in the examples below).
|
which is used in the examples below).
|
||||||
|
|
||||||
If you are using this client, you are very likely working with Elasticsearch,
|
If you are using this client, you are most likely working with {es}, and one of
|
||||||
and one of the first issues you will face is how to test your application.
|
the first issues you face is how to test your application. A perfectly valid
|
||||||
A perfectly valid solution is to use the real Elasticsearch instance for
|
solution is to use the real {es} instance for testing your application, but you
|
||||||
testing your application, but you would be doing an integration test,
|
would be doing an integration test, while you want a unit test. There are many
|
||||||
while you want a unit test.
|
ways to solve this problem, you could create the database with Docker, or use an
|
||||||
There are many ways to solve this problem, you could create the database
|
in-memory compatible one, but if you are writing unit tests that can be easily
|
||||||
with docker, or use an in-memory compatible one, but if you are writing
|
parallelized this becomes quite uncomfortable. A different way of improving your
|
||||||
unit tests that can be easily parallelized this will become quite uncomfortable.
|
testing experience while doing unit tests is to use a mock.
|
||||||
A different way of improving your testing experience while doing unit tests
|
|
||||||
is to use a mock.
|
|
||||||
|
|
||||||
The client is designed to be easy to extend and adapt to your needs.
|
The client is designed to be easy to extend and adapt to your needs. Thanks to
|
||||||
Thanks to its internal architecture it allows you to change some specific
|
its internal architecture it allows you to change some specific components while
|
||||||
components while keeping the rest of it working as usual.
|
keeping the rest of it working as usual. Each {es} official client is composed
|
||||||
Each Elasticsearch official client is composed of the following components:
|
of the following components:
|
||||||
|
|
||||||
* `API layer`: every Elasticsearch API that you can call
|
* `API layer`: every {es} API that you can call.
|
||||||
* `Transport`: a component that takes care of preparing a request before sending it and handling all the retry and sniffing strategies
|
* `Transport`: a component that takes care of preparing a request before sending
|
||||||
* `ConnectionPool`: Elasticsearch is a cluster and might have multiple nodes, the * `ConnectionPool` takes care of them
|
it and handling all the retry and sniffing strategies.
|
||||||
* `Serializer`: A class with all the serialization strategies, from the basic JSON to the new line delimited JSON.
|
* `ConnectionPool`: {es} is a cluster and might have multiple nodes, the
|
||||||
|
`ConnectionPool` takes care of them.
|
||||||
|
* `Serializer`: A class with all the serialization strategies, from the basic
|
||||||
|
JSON to the new line delimited JSON.
|
||||||
* `Connection`: The actual HTTP library.
|
* `Connection`: The actual HTTP library.
|
||||||
|
|
||||||
The best way to mock Elasticsearch with the official clients is to replace
|
The best way to mock {es} with the official clients is to replace the
|
||||||
the `Connection` component since it has very few responsibilities and
|
`Connection` component since it has very few responsibilities and it does not
|
||||||
it does not interact with other internal components other than getting
|
interact with other internal components other than getting requests and
|
||||||
requests and returning responses.
|
returning responses.
|
||||||
|
|
||||||
|
|
||||||
[discrete]
|
[discrete]
|
||||||
=== `@elastic/elasticsearch-mock`
|
==== `@elastic/elasticsearch-mock`
|
||||||
|
|
||||||
Writing each time a mock for your test can be annoying and error-prone,
|
Writing each time a mock for your test can be annoying and error-prone, so we
|
||||||
so we have built a simple yet powerful mocking library specifically designed
|
have built a simple yet powerful mocking library specifically designed for this
|
||||||
for this client, and you can install it with the following command:
|
client, and you can install it with the following command:
|
||||||
|
|
||||||
[source,sh]
|
[source,sh]
|
||||||
----
|
----
|
||||||
npm install @elastic/elasticsearch-mock --save-dev
|
npm install @elastic/elasticsearch-mock --save-dev
|
||||||
----
|
----
|
||||||
|
|
||||||
With this library you can easily create custom mocks for any request you can
|
With this library you can create custom mocks for any request you can send to
|
||||||
send to Elasticsearch. It offers a simple and intuitive API and it mocks only
|
{es}. It offers a simple and intuitive API and it mocks only the HTTP layer,
|
||||||
the HTTP layer, leaving the rest of the client working as usual.
|
leaving the rest of the client working as usual.
|
||||||
|
|
||||||
Before showing all of its features, and what you can do with it, let’s see an example:
|
Before showing all of its features, and what you can do with it, let’s see an
|
||||||
|
example:
|
||||||
|
|
||||||
[source,js]
|
[source,js]
|
||||||
----
|
----
|
||||||
@ -73,16 +75,16 @@ mock.add({
|
|||||||
client.info(console.log)
|
client.info(console.log)
|
||||||
----
|
----
|
||||||
|
|
||||||
As you can see it works closely with the client itself, once you have created
|
As you can see it works closely with the client itself, once you have created a
|
||||||
a new instance of the mock library you just need to call the mock.getConnection()
|
new instance of the mock library you just need to call the mock.getConnection()
|
||||||
method and pass its result to the Connection option of the client.
|
method and pass its result to the Connection option of the client. From now on,
|
||||||
From now on, every request will be handled by the mock library, and the HTTP
|
every request is handled by the mock library, and the HTTP layer will never be
|
||||||
layer will never be touched. As a result, your test will be significantly faster
|
touched. As a result, your test is significantly faster and you are able to
|
||||||
and you will be able to easily parallelize them!
|
easily parallelize them!
|
||||||
|
|
||||||
The library allows you to write both “strict” and “loose” mocks, which means
|
The library allows you to write both “strict” and “loose” mocks, which means
|
||||||
that you can write a mock that will handle a very specific request or be looser
|
that you can write a mock that handles a very specific request or be looser and
|
||||||
and handle a group of request, let’s see this in action:
|
handle a group of request, let’s see this in action:
|
||||||
|
|
||||||
[source,js]
|
[source,js]
|
||||||
----
|
----
|
||||||
@ -112,9 +114,9 @@ mock.add({
|
|||||||
})
|
})
|
||||||
----
|
----
|
||||||
|
|
||||||
In the example above every search request will get the first response,
|
In the example above, every search request gets the first response, while every
|
||||||
while every search request that uses the query described in the second mock,
|
search request that uses the query described in the second mock gets the second
|
||||||
will get the second response.
|
response.
|
||||||
|
|
||||||
You can also specify dynamic paths:
|
You can also specify dynamic paths:
|
||||||
|
|
||||||
@ -150,5 +152,6 @@ mock.add({
|
|||||||
})
|
})
|
||||||
----
|
----
|
||||||
|
|
||||||
We have seen how simple is mocking Elasticsearch and testing your application,
|
We have seen how simple is mocking {es} and testing your application, you can
|
||||||
you can find many more features and examples in the https://github.com/elastic/elasticsearch-js-mock[module documentation].
|
find many more features and examples in the
|
||||||
|
https://github.com/elastic/elasticsearch-js-mock[module documentation].
|
||||||
34
docs/transport.asciidoc
Normal file
34
docs/transport.asciidoc
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
[[transport]]
|
||||||
|
=== Transport
|
||||||
|
|
||||||
|
This class is responsible for performing the request to {es} and handling
|
||||||
|
errors, it also handles sniffing.
|
||||||
|
|
||||||
|
[source,js]
|
||||||
|
----
|
||||||
|
const { Client, Transport } = require('@elastic/elasticsearch')
|
||||||
|
|
||||||
|
class MyTransport extends Transport {
|
||||||
|
request (params, options, callback) {
|
||||||
|
// your code
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const client = new Client({
|
||||||
|
Transport: MyTransport
|
||||||
|
})
|
||||||
|
----
|
||||||
|
|
||||||
|
Sometimes you need to inject a small snippet of your code and then continue to
|
||||||
|
use the usual client code. In such cases, call `super.method`:
|
||||||
|
|
||||||
|
[source,js]
|
||||||
|
----
|
||||||
|
class MyTransport extends Transport {
|
||||||
|
request (params, options, callback) {
|
||||||
|
// your code
|
||||||
|
return super.request(params, options, callback)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
----
|
||||||
|
|
||||||
@ -1,17 +1,23 @@
|
|||||||
[[typescript]]
|
[[typescript]]
|
||||||
== TypeScript support
|
=== TypeScript support
|
||||||
|
|
||||||
The client offers a first-class support for TypeScript, since it ships the type
|
The client offers a first-class support for TypeScript, since it ships the type
|
||||||
definitions for every exposed API.
|
definitions for every exposed API.
|
||||||
|
|
||||||
NOTE: If you are using TypeScript you will be required to use _snake_case_ style
|
NOTE: If you are using TypeScript you need to use _snake_case_ style to define
|
||||||
to define the API parameters instead of _camelCase_.
|
the API parameters instead of _camelCase_.
|
||||||
|
|
||||||
By default event API uses https://www.typescriptlang.org/docs/handbook/generics.html[generics] to specify the requests and response bodies and the `meta.context`. Currently we can't provide those definitions, but we are working to improve this situation.
|
By default event API uses
|
||||||
|
https://www.typescriptlang.org/docs/handbook/generics.html[generics] to specify
|
||||||
|
the requests and response bodies and the `meta.context`. Currently, we can't
|
||||||
|
provide those definitions, but we are working to improve this situation.
|
||||||
|
|
||||||
You can find a partial definition of the request types by importing `RequestParams`, which is used by default in the client and accepts a body (when needed) as a generic to provide a better specification.
|
You can find a partial definition of the request types by importing
|
||||||
|
`RequestParams`, which is used by default in the client and accepts a body (when
|
||||||
|
needed) as a generic to provide a better specification.
|
||||||
|
|
||||||
The body defaults to `RequestBody` and `RequestNDBody`, which are defined as follows:
|
The body defaults to `RequestBody` and `RequestNDBody`, which are defined as
|
||||||
|
follows:
|
||||||
|
|
||||||
[source,ts]
|
[source,ts]
|
||||||
----
|
----
|
||||||
@ -39,7 +45,7 @@ You don't have to specify all the generics, but the order must be respected.
|
|||||||
|
|
||||||
|
|
||||||
[discrete]
|
[discrete]
|
||||||
=== A complete example
|
==== A complete example
|
||||||
|
|
||||||
[source,ts]
|
[source,ts]
|
||||||
----
|
----
|
||||||
|
|||||||
Reference in New Issue
Block a user