diff --git a/docs/advanced-config.asciidoc b/docs/advanced-config.asciidoc new file mode 100644 index 000000000..001c77432 --- /dev/null +++ b/docs/advanced-config.asciidoc @@ -0,0 +1,120 @@ +[[advanced-config]] +=== Advanced configuration + +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) + } +} +---- + + +[discrete] +==== `ConnectionPool` + +This class is responsible for keeping in memory all the {es} Connection that you +are using. There is a single Connection for every node. The connection pool +handles the resurrection strategies and the updates of the pool. + +[source,js] +---- +const { Client, ConnectionPool } = require('@elastic/elasticsearch') + +class MyConnectionPool extends ConnectionPool { + markAlive (connection) { + // your code + super.markAlive(connection) + } +} + +const client = new Client({ + ConnectionPool: MyConnectionPool +}) +---- + + +[discrete] +==== `Connection` + +This class represents a single node, it holds every information we have on the +node, such as roles, id, URL, custom headers and so on. The actual HTTP request +is performed here, this means that if you want to swap the default HTTP client +(Node.js core), you should override the `request` method of this class. + +[source,js] +---- +const { Client, Connection } = require('@elastic/elasticsearch') + +class MyConnection extends Connection { + request (params, callback) { + // your code + } +} + +const client = new Client({ + Connection: MyConnection +}) +---- + + +[discrete] +==== `Serializer` + +This class is responsible for the serialization of every request, it offers the +following methods: + +* `serialize(object: any): string;` serializes request objects. +* `deserialize(json: string): any;` deserializes response strings. +* `ndserialize(array: any[]): string;` serializes bulk request objects. +* `qserialize(object: any): string;` serializes request query parameters. + +[source,js] +---- +const { Client, Serializer } = require('@elastic/elasticsearch') + +class MySerializer extends Serializer { + serialize (object) { + // your code + } +} + +const client = new Client({ + Serializer: MySerializer +}) +---- \ No newline at end of file diff --git a/docs/basic-config.asciidoc b/docs/basic-config.asciidoc new file mode 100644 index 000000000..a6a4b41d5 --- /dev/null +++ b/docs/basic-config.asciidoc @@ -0,0 +1,247 @@ +[[basic-config]] +=== Basic configuration + +This page shows you the possible basic configuration options that the clients +offers. + + +[source,js] +---- +const { Client } = require('@elastic/elasticsearch') + +const client = new Client({ + node: 'http://localhost:9200', + maxRetries: 5, + requestTimeout: 60000, + sniffOnStart: true +}) +---- + + +[cols=2*] +|=== +|`node` or `nodes` +a|The Elasticsearch endpoint to use. + +It can be a single string or an array of strings: +[source,js] +---- +node: 'http://localhost:9200' +---- +Or it can be an object (or an array of objects) that represents the node: +[source,js] +---- +node: { + url: new URL('http://localhost:9200'), + ssl: 'ssl options', + agent: 'http agent options', + id: 'custom node id', + headers: { 'custom': 'headers' } + roles: { + master: true, + data: true, + ingest: true, + ml: false + } +} +---- + +|`auth` +a|Your authentication data. You can use both basic authentication and +{ref}/security-api-create-api-key.html[ApiKey]. + +See https://www.elastic.co/guide/en/elasticsearch/client/javascript-api/current/auth-reference.html[Authentication] +for more details. + +_Default:_ `null` + +Basic authentication: +[source,js] +---- +auth: { + username: 'elastic', + password: 'changeme' +} +---- +{ref}/security-api-create-api-key.html[ApiKey] authentication: +[source,js] +---- +auth: { + apiKey: 'base64EncodedKey' +} +---- + + +|`maxRetries` +|`number` - Max number of retries for each request. + +_Default:_ `3` + +|`requestTimeout` +|`number` - Max request timeout in milliseconds for each request. + +_Default:_ `30000` + +|`pingTimeout` +|`number` - Max ping request timeout in milliseconds for each request. + +_Default:_ `3000` + +|`sniffInterval` +|`number, boolean` - Perform a sniff operation every `n` milliseconds. Sniffing might not be the best solution for you, take a look https://www.elastic.co/blog/elasticsearch-sniffing-best-practices-what-when-why-how[here] to know more. + +_Default:_ `false` + +|`sniffOnStart` +|`boolean` - Perform a sniff once the client is started. Sniffing might not be the best solution for you, take a look https://www.elastic.co/blog/elasticsearch-sniffing-best-practices-what-when-why-how[here] to know more. + +_Default:_ `false` + +|`sniffEndpoint` +|`string` - Endpoint to ping during a sniff. + +_Default:_ `'_nodes/_all/http'` + +|`sniffOnConnectionFault` +|`boolean` - Perform a sniff on connection fault. Sniffing might not be the best solution for you, take a look https://www.elastic.co/blog/elasticsearch-sniffing-best-practices-what-when-why-how[here] to know more. + +_Default:_ `false` + +|`resurrectStrategy` +|`string` - Configure the node resurrection strategy. + +_Options:_ `'ping'`, `'optimistic'`, `'none'` + +_Default:_ `'ping'` + +|`suggestCompression` +|`boolean` - Adds `accept-encoding` header to every request. + +_Default:_ `false` + +|`compression` +|`string, boolean` - Enables gzip request body compression. + +_Options:_ `'gzip'`, `false` + +_Default:_ `false` + +|`ssl` +|`http.SecureContextOptions` - ssl https://nodejs.org/api/tls.html[configuraton]. + +_Default:_ `null` + +|`proxy` +a|`string, URL` - If you are using an http(s) proxy, you can put its url here. +The client will automatically handle the connection to it. + +_Default:_ `null` +[source,js] +---- +const client = new Client({ + node: 'http://localhost:9200', + proxy: 'http://localhost:8080' +}) + +// Proxy with basic authentication +const client = new Client({ + node: 'http://localhost:9200', + proxy: 'http://user:pwd@localhost:8080' +}) +---- + +|`agent` +a|`http.AgentOptions, function` - http agent https://nodejs.org/api/http.html#http_new_agent_options[options], +or a function that returns an actual http agent instance. If you want to disable the http agent use entirely +(and disable the `keep-alive` feature), set the agent to `false`. + +_Default:_ `null` +[source,js] +---- +const client = new Client({ + node: 'http://localhost:9200', + agent: { agent: 'options' } +}) + +const client = new Client({ + node: 'http://localhost:9200', + // the function takes as parameter the option + // object passed to the Connection constructor + agent: (opts) => new CustomAgent() +}) + +const client = new Client({ + node: 'http://localhost:9200', + // Disable agent and keep-alive + agent: false +}) +---- + +|`nodeFilter` +a|`function` - Filters which node not to use for a request. + +_Default:_ +[source,js] +---- +function defaultNodeFilter (node) { + // avoid master only nodes + if (node.roles.master === true && + node.roles.data === false && + node.roles.ingest === false) { + return false + } + return true +} +---- + +|`nodeSelector` +a|`function` - custom selection strategy. + +_Options:_ `'round-robin'`, `'random'`, custom function + +_Default:_ `'round-robin'` + +_Custom function example:_ +[source,js] +---- +function nodeSelector (connections) { + const index = calculateIndex() + return connections[index] +} +---- + +|`generateRequestId` +a|`function` - function to generate the request id for every request, it takes +two parameters, the request parameters and options. + +By default it generates an incremental integer for every request. + +_Custom function example:_ +[source,js] +---- +function generateRequestId (params, options) { + // your id generation logic + // must be syncronous + return 'id' +} +---- + +|`name` +|`string, symbol` - The name to identify the client instance in the events. + +_Default:_ `elasticsearch-js` + +|`opaqueIdPrefix` +|`string` - A string that will be use to prefix any `X-Opaque-Id` header. + +See https://www.elastic.co/guide/en/elasticsearch/client/javascript-api/current/observability.html#_x-opaque-id_support[`X-Opaque-Id` support] for more details. + +_Default:_ `null` + +|`headers` +|`object` - A set of custom headers to send in every request. + +_Default:_ `{}` + +|`context` +|`object` - A custom object that you can use for observability in your events. +It will be merged with the API level context option. + +_Default:_ `null` + +|`enableMetaHeader` +|`boolean` - If true, adds an header named `'x-elastic-client-meta'`, containing some minimal telemetry data, +such as the client and platform version. + +_Default:_ `true` + +|`cloud` +a|`object` - Custom configuration for connecting to +https://cloud.elastic.co[Elastic Cloud]. See https://www.elastic.co/guide/en/elasticsearch/client/javascript-api/current/auth-reference.html[Authentication] +for more details. + +_Default:_ `null` + +_Cloud configuration example:_ +[source,js] +---- +const client = new Client({ + cloud: { + id: 'name:bG9jYWxob3N0JGFiY2QkZWZnaA==' + }, + auth: { + username: 'elastic', + password: 'changeme' + } +}) +---- + +|=== \ No newline at end of file diff --git a/docs/child.asciidoc b/docs/child.asciidoc index 2e5a49136..3d8e40a96 100644 --- a/docs/child.asciidoc +++ b/docs/child.asciidoc @@ -1,5 +1,5 @@ -[[child-client]] -== Creating a child client +[[child]] +=== Creating a child client There are some use cases where you may need multiple instances of the client. You can easily do that by calling `new Client()` as many times as you need, but diff --git a/docs/configuration.asciidoc b/docs/configuration.asciidoc index a173d8161..cca46ecee 100644 --- a/docs/configuration.asciidoc +++ b/docs/configuration.asciidoc @@ -1,371 +1,11 @@ [[client-configuration]] -== Client configuration +== Configuration + The client is designed to be easily configured for your needs. In the following -section, you can see the possible basic options that you can use to configure -it. +section, you can see the possible options that you can use to configure it. -[source,js] ----- -const { Client } = require('@elastic/elasticsearch') - -const client = new Client({ - node: 'http://localhost:9200', - maxRetries: 5, - requestTimeout: 60000, - sniffOnStart: true -}) ----- - -[discrete] -=== Basic options - -[cols=2*] -|=== -|`node` or `nodes` -a|The Elasticsearch endpoint to use. + -It can be a single string or an array of strings: -[source,js] ----- -node: 'http://localhost:9200' ----- -Or it can be an object (or an array of objects) that represents the node: -[source,js] ----- -node: { - url: new URL('http://localhost:9200'), - ssl: 'ssl options', - agent: 'http agent options', - id: 'custom node id', - headers: { 'custom': 'headers' } - roles: { - master: true, - data: true, - ingest: true, - ml: false - } -} ----- - -|`auth` -a|Your authentication data. You can use both basic authentication and -{ref}/security-api-create-api-key.html[ApiKey]. + -See https://www.elastic.co/guide/en/elasticsearch/client/javascript-api/current/auth-reference.html[Authentication] -for more details. + -_Default:_ `null` - -Basic authentication: -[source,js] ----- -auth: { - username: 'elastic', - password: 'changeme' -} ----- -{ref}/security-api-create-api-key.html[ApiKey] authentication: -[source,js] ----- -auth: { - apiKey: 'base64EncodedKey' -} ----- - - -|`maxRetries` -|`number` - Max number of retries for each request. + -_Default:_ `3` - -|`requestTimeout` -|`number` - Max request timeout in milliseconds for each request. + -_Default:_ `30000` - -|`pingTimeout` -|`number` - Max ping request timeout in milliseconds for each request. + -_Default:_ `3000` - -|`sniffInterval` -|`number, boolean` - Perform a sniff operation every `n` milliseconds. Sniffing might not be the best solution for you, take a look https://www.elastic.co/blog/elasticsearch-sniffing-best-practices-what-when-why-how[here] to know more. + -_Default:_ `false` - -|`sniffOnStart` -|`boolean` - Perform a sniff once the client is started. Sniffing might not be the best solution for you, take a look https://www.elastic.co/blog/elasticsearch-sniffing-best-practices-what-when-why-how[here] to know more. + -_Default:_ `false` - -|`sniffEndpoint` -|`string` - Endpoint to ping during a sniff. + -_Default:_ `'_nodes/_all/http'` - -|`sniffOnConnectionFault` -|`boolean` - Perform a sniff on connection fault. Sniffing might not be the best solution for you, take a look https://www.elastic.co/blog/elasticsearch-sniffing-best-practices-what-when-why-how[here] to know more. + -_Default:_ `false` - -|`resurrectStrategy` -|`string` - Configure the node resurrection strategy. + -_Options:_ `'ping'`, `'optimistic'`, `'none'` + -_Default:_ `'ping'` - -|`suggestCompression` -|`boolean` - Adds `accept-encoding` header to every request. + -_Default:_ `false` - -|`compression` -|`string, boolean` - Enables gzip request body compression. + -_Options:_ `'gzip'`, `false` + -_Default:_ `false` - -|`ssl` -|`http.SecureContextOptions` - ssl https://nodejs.org/api/tls.html[configuraton]. + -_Default:_ `null` - -|`proxy` -a|`string, URL` - If you are using an http(s) proxy, you can put its url here. -The client will automatically handle the connection to it. + -_Default:_ `null` -[source,js] ----- -const client = new Client({ - node: 'http://localhost:9200', - proxy: 'http://localhost:8080' -}) - -// Proxy with basic authentication -const client = new Client({ - node: 'http://localhost:9200', - proxy: 'http://user:pwd@localhost:8080' -}) ----- - -|`agent` -a|`http.AgentOptions, function` - http agent https://nodejs.org/api/http.html#http_new_agent_options[options], -or a function that returns an actual http agent instance. If you want to disable the http agent use entirely -(and disable the `keep-alive` feature), set the agent to `false`. + -_Default:_ `null` -[source,js] ----- -const client = new Client({ - node: 'http://localhost:9200', - agent: { agent: 'options' } -}) - -const client = new Client({ - node: 'http://localhost:9200', - // the function takes as parameter the option - // object passed to the Connection constructor - agent: (opts) => new CustomAgent() -}) - -const client = new Client({ - node: 'http://localhost:9200', - // Disable agent and keep-alive - agent: false -}) ----- - -|`nodeFilter` -a|`function` - Filters which node not to use for a request. + -_Default:_ -[source,js] ----- -function defaultNodeFilter (node) { - // avoid master only nodes - if (node.roles.master === true && - node.roles.data === false && - node.roles.ingest === false) { - return false - } - return true -} ----- - -|`nodeSelector` -a|`function` - custom selection strategy. + -_Options:_ `'round-robin'`, `'random'`, custom function + -_Default:_ `'round-robin'` + -_Custom function example:_ -[source,js] ----- -function nodeSelector (connections) { - const index = calculateIndex() - return connections[index] -} ----- - -|`generateRequestId` -a|`function` - function to generate the request id for every request, it takes -two parameters, the request parameters and options. + -By default it generates an incremental integer for every request. + -_Custom function example:_ -[source,js] ----- -function generateRequestId (params, options) { - // your id generation logic - // must be syncronous - return 'id' -} ----- - -|`name` -|`string, symbol` - The name to identify the client instance in the events. + -_Default:_ `elasticsearch-js` - -|`opaqueIdPrefix` -|`string` - A string that will be use to prefix any `X-Opaque-Id` header. + -See https://www.elastic.co/guide/en/elasticsearch/client/javascript-api/current/observability.html#_x-opaque-id_support[`X-Opaque-Id` support] for more details. + -_Default:_ `null` - -|`headers` -|`object` - A set of custom headers to send in every request. + -_Default:_ `{}` - -|`context` -|`object` - A custom object that you can use for observability in your events. -It will be merged with the API level context option. + -_Default:_ `null` - -|`enableMetaHeader` -|`boolean` - If true, adds an header named `'x-elastic-client-meta'`, containing some minimal telemetry data, -such as the client and platform version. + -_Default:_ `true` - -|`cloud` -a|`object` - Custom configuration for connecting to -https://cloud.elastic.co[Elastic Cloud]. See https://www.elastic.co/guide/en/elasticsearch/client/javascript-api/current/auth-reference.html[Authentication] -for more details. + -_Default:_ `null` + -_Cloud configuration example:_ -[source,js] ----- -const client = new Client({ - cloud: { - id: 'name:bG9jYWxob3N0JGFiY2QkZWZnaA==' - }, - auth: { - username: 'elastic', - password: 'changeme' - } -}) ----- - -|=== - - -[discrete] -=== Advanced configuration - -If you need to customize the client behavior heavily, you are in the right -place! The client allows 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) - } -} ----- - - -[discrete] -=== `ConnectionPool` - -This class is responsible for keeping in memory all the {es} Connection that we -are using. There is a single Connection for every node. The connection pool -handles the resurrection strategies and the updates of the pool. - -[source,js] ----- -const { Client, ConnectionPool } = require('@elastic/elasticsearch') - -class MyConnectionPool extends ConnectionPool { - markAlive (connection) { - // your code - super.markAlive(connection) - } -} - -const client = new Client({ - ConnectionPool: MyConnectionPool -}) ----- - - -[discrete] -=== `Connection` - -This class represents a single node, it holds every information we have on the -node, such as roles, id, URL, custom headers and so on. The actual HTTP request -is performed here, this means that if you want to swap the default HTTP client -(Node.js core), you should override the `request` method of this class. - -[source,js] ----- -const { Client, Connection } = require('@elastic/elasticsearch') - -class MyConnection extends Connection { - request (params, callback) { - // your code - } -} - -const client = new Client({ - Connection: MyConnection -}) ----- - - -[discrete] -=== `Serializer` - -This class is responsible for the serialization of every request, it offers the -following methods: - -* `serialize(object: any): string;` serializes request objects. -* `deserialize(json: string): any;` deserializes response strings. -* `ndserialize(array: any[]): string;` serializes bulk request objects. -* `qserialize(object: any): string;` serializes request query parameters. - -[source,js] ----- -const { Client, Serializer } = require('@elastic/elasticsearch') - -class MySerializer extends Serializer { - serialize (object) { - // your code - } -} - -const client = new Client({ - Serializer: MySerializer -}) ----- +* <> +* <> +* <> +* <> diff --git a/docs/extend.asciidoc b/docs/extend.asciidoc index 0e9d2a532..069cacd86 100644 --- a/docs/extend.asciidoc +++ b/docs/extend.asciidoc @@ -1,5 +1,5 @@ -[[extend-client]] -== Extend the client +[[extend]] +=== Extend the client Sometimes you need to reuse the same logic, or you want to build a custom API to allow you simplify your code. The easiest way to achieve that is by extending diff --git a/docs/index.asciidoc b/docs/index.asciidoc index c1e6bc831..b52b68787 100644 --- a/docs/index.asciidoc +++ b/docs/index.asciidoc @@ -8,11 +8,13 @@ include::installation.asciidoc[] include::connecting.asciidoc[] include::changelog.asciidoc[] include::configuration.asciidoc[] +include::basic-config.asciidoc[] +include::advanced-config.asciidoc[] +include::child.asciidoc[] +include::extend.asciidoc[] include::reference.asciidoc[] include::breaking-changes.asciidoc[] include::observability.asciidoc[] -include::child.asciidoc[] -include::extend.asciidoc[] include::helpers.asciidoc[] include::typescript.asciidoc[] include::testing.asciidoc[]