[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
|
||||
place! The client enables you to customize the following internals:
|
||||
|
||||
* `Transport` class
|
||||
* `ConnectionPool` class
|
||||
* `Connection` class
|
||||
* `Serializer` class
|
||||
|
||||
|
||||
[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)
|
||||
}
|
||||
}
|
||||
----
|
||||
NOTE: For information about the `Transport` class, refer to <<transport>>.
|
||||
|
||||
|
||||
[discrete]
|
||||
|
||||
@ -9,3 +9,4 @@ section, you can see the possible options that you can use to configure it.
|
||||
* <<advanced-config>>
|
||||
* <<child>>
|
||||
* <<extend>>
|
||||
* <<client-testing>>
|
||||
|
||||
@ -11,10 +11,12 @@ include::basic-config.asciidoc[]
|
||||
include::advanced-config.asciidoc[]
|
||||
include::child.asciidoc[]
|
||||
include::extend.asciidoc[]
|
||||
include::testing.asciidoc[]
|
||||
include::integrations.asciidoc[]
|
||||
include::observability.asciidoc[]
|
||||
include::transport.asciidoc[]
|
||||
include::typescript.asciidoc[]
|
||||
include::reference.asciidoc[]
|
||||
include::breaking-changes.asciidoc[]
|
||||
include::observability.asciidoc[]
|
||||
include::helpers.asciidoc[]
|
||||
include::typescript.asciidoc[]
|
||||
include::testing.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
|
||||
|
||||
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
|
||||
`response`.
|
||||
|
||||
Correlating those events can be quite hard, especially if your applications have
|
||||
a large codebase with many events happening at the same time.
|
||||
Correlating those events can be hard, especially if your applications have a
|
||||
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
|
||||
features. Let's see them in action.
|
||||
|
||||
|
||||
[discrete]
|
||||
=== Events
|
||||
==== Events
|
||||
|
||||
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
|
||||
@ -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]
|
||||
----
|
||||
@ -132,7 +133,7 @@ meta: {
|
||||
----
|
||||
|
||||
|
||||
While the `result` value in `resurrect` will be:
|
||||
While the `result` value in `resurrect` is:
|
||||
|
||||
[source,ts]
|
||||
----
|
||||
@ -146,10 +147,13 @@ request: {
|
||||
----
|
||||
|
||||
[discrete]
|
||||
==== Events order
|
||||
===== Events order
|
||||
|
||||
The event order is described in the following graph, in some edge cases, the 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.
|
||||
The event order is described in the following graph, in some edge cases, the
|
||||
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]
|
||||
----
|
||||
@ -170,11 +174,11 @@ serialization
|
||||
|
||||
|
||||
[discrete]
|
||||
=== Correlation id
|
||||
==== Correlation id
|
||||
|
||||
Correlating events can be quite hard, especially if there are many events at the
|
||||
same time. The client offers you an automatic (and configurable) system to help
|
||||
you handle this problem.
|
||||
Correlating events can be hard, especially if there are many events at the same
|
||||
time. The client offers you an automatic (and configurable) system to help you
|
||||
handle this problem.
|
||||
|
||||
[source,js]
|
||||
----
|
||||
@ -204,8 +208,8 @@ client.search({
|
||||
----
|
||||
|
||||
|
||||
By default the id is an incremental integer, but you can easily configure that
|
||||
with the `generateRequestId` option:
|
||||
By default the id is an incremental integer, but you can configure it with the
|
||||
`generateRequestId` option:
|
||||
|
||||
[source,js]
|
||||
----
|
||||
@ -238,7 +242,7 @@ client.search({
|
||||
|
||||
|
||||
[discrete]
|
||||
=== Context object
|
||||
==== Context object
|
||||
|
||||
Sometimes, you might need to make some custom data available in your events, you
|
||||
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
|
||||
configuration. If you provide both, the two context object will be shallow merged,
|
||||
and the API level object will take precedece.
|
||||
configuration. If you provide both, the two context objects will be shallow
|
||||
merged, and the API level object will take precedence.
|
||||
|
||||
[source,js]
|
||||
----
|
||||
@ -314,12 +318,12 @@ client.search({
|
||||
|
||||
|
||||
[discrete]
|
||||
=== Client name
|
||||
==== Client name
|
||||
|
||||
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
|
||||
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]
|
||||
----
|
||||
@ -368,13 +372,13 @@ child.search({
|
||||
|
||||
|
||||
[discrete]
|
||||
=== X-Opaque-Id support
|
||||
==== X-Opaque-Id support
|
||||
|
||||
To improve the overall observability, the client offers an easy way to configure
|
||||
the `X-Opaque-Id` header. If you set the `X-Opaque-Id` in a specific request,
|
||||
this will allow you to discover this identifier in the
|
||||
To improve observability, the client offers an easy way to configure the
|
||||
`X-Opaque-Id` header. If you set the `X-Opaque-Id` in a specific request, this
|
||||
allows you to discover this identifier in the
|
||||
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].
|
||||
|
||||
The `X-Opaque-Id` should be configured in each request, for doing that you can
|
||||
|
||||
@ -1,56 +1,58 @@
|
||||
[[client-testing]]
|
||||
== Testing
|
||||
=== Testing
|
||||
|
||||
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
|
||||
most testing frameworks (such as https://www.npmjs.com/package/ava[`ava`],
|
||||
which is used in the examples below).
|
||||
|
||||
If you are using this client, you are very likely working with Elasticsearch,
|
||||
and one of the first issues you will face is how to test your application.
|
||||
A perfectly valid solution is to use the real Elasticsearch instance for
|
||||
testing your application, but you would be doing an integration test,
|
||||
while you want a unit test.
|
||||
There are many ways to solve this problem, you could create the database
|
||||
with docker, or use an in-memory compatible one, but if you are writing
|
||||
unit tests that can be easily parallelized this will become quite uncomfortable.
|
||||
A different way of improving your testing experience while doing unit tests
|
||||
is to use a mock.
|
||||
If you are using this client, you are most likely working with {es}, and one of
|
||||
the first issues you face is how to test your application. A perfectly valid
|
||||
solution is to use the real {es} instance for testing your application, but you
|
||||
would be doing an integration test, while you want a unit test. There are many
|
||||
ways to solve this problem, you could create the database with Docker, or use an
|
||||
in-memory compatible one, but if you are writing unit tests that can be easily
|
||||
parallelized this becomes quite uncomfortable. 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.
|
||||
Thanks to its internal architecture it allows you to change some specific
|
||||
components while keeping the rest of it working as usual.
|
||||
Each Elasticsearch official client is composed of the following components:
|
||||
The client is designed to be easy to extend and adapt to your needs. Thanks to
|
||||
its internal architecture it allows you to change some specific components while
|
||||
keeping the rest of it working as usual. Each {es} official client is composed
|
||||
of the following components:
|
||||
|
||||
* `API layer`: every Elasticsearch 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
|
||||
* `ConnectionPool`: Elasticsearch 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.
|
||||
* `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.
|
||||
* `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.
|
||||
|
||||
The best way to mock Elasticsearch with the official clients is to replace
|
||||
the `Connection` component since it has very few responsibilities and
|
||||
it does not interact with other internal components other than getting
|
||||
requests and returning responses.
|
||||
The best way to mock {es} with the official clients is to replace the
|
||||
`Connection` component since it has very few responsibilities and it does not
|
||||
interact with other internal components other than getting requests and
|
||||
returning responses.
|
||||
|
||||
|
||||
[discrete]
|
||||
=== `@elastic/elasticsearch-mock`
|
||||
==== `@elastic/elasticsearch-mock`
|
||||
|
||||
Writing each time a mock for your test can be annoying and error-prone,
|
||||
so we have built a simple yet powerful mocking library specifically designed
|
||||
for this client, and you can install it with the following command:
|
||||
Writing each time a mock for your test can be annoying and error-prone, so we
|
||||
have built a simple yet powerful mocking library specifically designed for this
|
||||
client, and you can install it with the following command:
|
||||
|
||||
[source,sh]
|
||||
----
|
||||
npm install @elastic/elasticsearch-mock --save-dev
|
||||
----
|
||||
|
||||
With this library you can easily create custom mocks for any request you can
|
||||
send to Elasticsearch. It offers a simple and intuitive API and it mocks only
|
||||
the HTTP layer, leaving the rest of the client working as usual.
|
||||
With this library you can create custom mocks for any request you can send to
|
||||
{es}. It offers a simple and intuitive API and it mocks only the HTTP layer,
|
||||
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]
|
||||
----
|
||||
@ -73,16 +75,16 @@ mock.add({
|
||||
client.info(console.log)
|
||||
----
|
||||
|
||||
As you can see it works closely with the client itself, once you have created
|
||||
a 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.
|
||||
From now on, every request will be handled by the mock library, and the HTTP
|
||||
layer will never be touched. As a result, your test will be significantly faster
|
||||
and you will be able to easily parallelize them!
|
||||
As you can see it works closely with the client itself, once you have created a
|
||||
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. From now on,
|
||||
every request is handled by the mock library, and the HTTP layer will never be
|
||||
touched. As a result, your test is significantly faster and you are able to
|
||||
easily parallelize them!
|
||||
|
||||
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
|
||||
and handle a group of request, let’s see this in action:
|
||||
that you can write a mock that handles a very specific request or be looser and
|
||||
handle a group of request, let’s see this in action:
|
||||
|
||||
[source,js]
|
||||
----
|
||||
@ -112,9 +114,9 @@ mock.add({
|
||||
})
|
||||
----
|
||||
|
||||
In the example above every search request will get the first response,
|
||||
while every search request that uses the query described in the second mock,
|
||||
will get the second response.
|
||||
In the example above, every search request gets the first response, while every
|
||||
search request that uses the query described in the second mock gets the second
|
||||
response.
|
||||
|
||||
You can also specify dynamic paths:
|
||||
|
||||
@ -150,5 +152,6 @@ mock.add({
|
||||
})
|
||||
----
|
||||
|
||||
We have seen how simple is mocking Elasticsearch and testing your application,
|
||||
you can find many more features and examples in the https://github.com/elastic/elasticsearch-js-mock[module documentation].
|
||||
We have seen how simple is mocking {es} and testing your application, you can
|
||||
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 support
|
||||
=== TypeScript support
|
||||
|
||||
The client offers a first-class support for TypeScript, since it ships the type
|
||||
definitions for every exposed API.
|
||||
|
||||
NOTE: If you are using TypeScript you will be required to use _snake_case_ style
|
||||
to define the API parameters instead of _camelCase_.
|
||||
NOTE: If you are using TypeScript you need to use _snake_case_ style to define
|
||||
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]
|
||||
----
|
||||
@ -39,7 +45,7 @@ You don't have to specify all the generics, but the order must be respected.
|
||||
|
||||
|
||||
[discrete]
|
||||
=== A complete example
|
||||
==== A complete example
|
||||
|
||||
[source,ts]
|
||||
----
|
||||
|
||||
Reference in New Issue
Block a user