1[[per_request_configuration]]
2=== Per-request configuration
3
4There are several configurations that can be set on a per-request basis, rather
5than at a connection- or client-level. These are specified as part of the
6request associative array.
7
8
9==== Request Identification
10
11You can enrich your requests against {es} with an identifier string, that allows
12you to discover this identifier in
13https://www.elastic.co/guide/en/elasticsearch/reference/7.4/logging.html#deprecation-logging[deprecation logs],
14to support you with
15https://www.elastic.co/guide/en/elasticsearch/reference/7.4/index-modules-slowlog.html#_identifying_search_slow_log_origin[identifying search slow log origin]
16or to help with
17https://www.elastic.co/guide/en/elasticsearch/reference/current/tasks.html#_identifying_running_tasks[identifying running tasks].
18
19
20[source,php]
21----
22$client = ClientBuilder::create()->build();
23
24$params = [
25    'index' => 'test',
26    'id'    => 1,
27    'client' => [
28        'opaqueId' => 'app17@dc06.eu_user1234', <1>
29    ]
30];
31$response = $client->get($params);
32
33----
34<1> This populates the `X-Opaque-Id` header with the value
35`app17@dc06.eu_user1234`.
36
37
38==== Ignoring exceptions
39
40The library attempts to throw exceptions for common problems. These exceptions
41match the HTTP response code provided by {es}. For example, attempting to GET a
42nonexistent document will throw a `Missing404Exception`.
43
44Exceptions are a useful and consistent way to deal with problems like missing
45documents, syntax errors, version conflicts, and so on. But sometimes you want
46to deal with the response body rather than catch exceptions (often useful in
47test suites).
48
49If you need that behavior, you can configure an `ignore` parameter. You can
50configure it in the `client` parameter of the request array. For instance, the
51example below ignores the `Missing404Exception` exception and returns
52the JSON provided by {es} instead.
53
54
55[source,php]
56----
57$client = ClientBuilder::create()->build();
58
59$params = [
60    'index'  => 'test_missing',
61    'id'     => 1,
62    'client' => [ 'ignore' => 404 ] <1>
63];
64echo $client->get($params);
65
66> {"_index":"test_missing","_type":"_doc","_id":"1","found":false}
67----
68<1> This ignores the 404 missing exception.
69
70You can specify multiple HTTP status codes to ignore by providing an array of
71values:
72
73[source,php]
74----
75$client = ClientBuilder::create()->build();
76
77$params = [
78    'index'  => 'test_missing',
79    'client' => [ 'ignore' => [400, 404] ] <1>
80];
81echo $client->get($params);
82
83> No handler found for uri [/test_missing/test/] and method [GET]
84
85----
86<1> `ignore` also accepts an array of exceptions to ignore. In this example, the
87`BadRequest400Exception` is being ignored.
88
89It should be noted that the response is a string which may or may not be encoded
90as JSON. In the first example, the response body is a complete JSON object which
91could be decoded. In the second example, it was simply a string.
92
93Since the client has no way of knowing what the exception response will contain,
94no attempts to decode it are taken.
95
96
97==== Providing custom query parameters
98
99Sometimes you need to provide custom query parameters, such as authentication
100tokens for a third-party plugin or proxy. All query parameters are allow listed
101in Elasticsearch-php, which is to protect you from specifying a parameter which
102is not accepted by {es}.
103
104If you need custom parameters, you need to bypass this allow listing mechanism.
105To do so, add them to the `custom` parameter as an array of values:
106
107[source,php]
108----
109$client = ClientBuilder::create()->build();
110
111$params = [
112    'index'  => 'test',
113    'id'     => 1,
114    'parent' => 'abc',              // allowlisted Elasticsearch parameter
115    'client' => [
116        'custom' => [
117            'customToken' => 'abc', // user-defined, not allow listed, not checked
118            'otherToken'  => 123
119        ]
120    ]
121];
122$exists = $client->exists($params);
123----
124
125
126==== Increasing the verbosity of responses
127
128By default, the client only returns the response body. If you require more
129information (for example, stats about the transfer, headers, status codes, and
130so on), you can tell the client to return a more verbose response. This is
131enabled via the `verbose` parameter in the client options.
132
133Without verbosity, all you see is the response body:
134
135[source,php]
136----
137$client = ClientBuilder::create()->build();
138
139$params = [
140    'index' => 'test',
141    'id'    => 1
142];
143$response = $client->get($params);
144print_r($response);
145
146
147Array
148(
149    [_index] => test
150    [_type] => _doc
151    [_id] => 1
152    [_version] => 1
153    [found] => 1
154    [_source] => Array
155        (
156            [field] => value
157        )
158
159)
160----
161
162With verbosity turned on, you will see all of the transfer stats:
163
164[source,php]
165----
166$client = ClientBuilder::create()->build();
167
168$params = [
169    'index'  => 'test',
170    'id'     => 1,
171    'client' => [
172        'verbose' => true
173    ]
174];
175$response = $client->get($params);
176print_r($response);
177
178
179Array
180(
181    [transfer_stats] => Array
182        (
183            [url] => http://127.0.0.1:9200/test/test/1
184            [content_type] => application/json; charset=UTF-8
185            [http_code] => 200
186            [header_size] => 86
187            [request_size] => 51
188            [filetime] => -1
189            [ssl_verify_result] => 0
190            [redirect_count] => 0
191            [total_time] => 0.00289
192            [namelookup_time] => 9.7E-5
193            [connect_time] => 0.000265
194            [pretransfer_time] => 0.000322
195            [size_upload] => 0
196            [size_download] => 96
197            [speed_download] => 33217
198            [speed_upload] => 0
199            [download_content_length] => 96
200            [upload_content_length] => -1
201            [starttransfer_time] => 0.002796
202            [redirect_time] => 0
203            [redirect_url] =>
204            [primary_ip] => 127.0.0.1
205            [certinfo] => Array
206                (
207                )
208
209            [primary_port] => 9200
210            [local_ip] => 127.0.0.1
211            [local_port] => 62971
212        )
213
214    [curl] => Array
215        (
216            [error] =>
217            [errno] => 0
218        )
219
220    [effective_url] => http://127.0.0.1:9200/test/test/1
221    [headers] => Array
222        (
223            [Content-Type] => Array
224                (
225                    [0] => application/json; charset=UTF-8
226                )
227
228            [Content-Length] => Array
229                (
230                    [0] => 96
231                )
232
233        )
234
235    [status] => 200
236    [reason] => OK
237    [body] => Array
238        (
239            [_index] => test
240            [_type] => _doc
241            [_id] => 1
242            [_version] => 1
243            [found] => 1
244            [_source] => Array
245                (
246                    [field] => value
247                )
248        )
249)
250----
251
252==== Curl Timeouts
253
254It is possible to configure per-request curl timeouts via the `timeout` and
255`connect_timeout` parameters. These control the client-side, curl timeouts. The
256`connect_timeout` parameter controls how long curl should wait for the "connect"
257phase to finish, while the `timeout` parameter controls how long curl should
258wait for the entire request to finish.
259
260If either timeout expires, curl closes the connection and returns an error. Both
261parameters should be specified in seconds.
262
263Note: client-side timeouts *do not* mean that {es} aborts the request. {es} will
264continue executing the request until it completes. In the case of a slow query
265or bulk request, the operation continues executing "in the background", unknown
266to your client. If your client kills connections rapidly with a timeout, only to
267immediately execute another request, it is possible to swamp the server with
268many connections because there is no "back-pressure" on the client. In these
269situations, you will see the appropriate threadpool queue growing in size, and
270may start receiving `EsRejectedExecutionException` exceptions from {es} when the
271queue finally reaches capacity.
272
273
274[source,php]
275----
276$client = ClientBuilder::create()->build();
277
278$params = [
279    'index'  => 'test',
280    'id'     => 1,
281    'client' => [
282        'timeout' => 10,        // ten second timeout
283        'connect_timeout' => 10
284    ]
285];
286$response = $client->get($params);
287----
288
289
290==== Enabling Future Mode
291
292The client supports asynchronous, batch processing of requests. This is enabled
293(if your HTTP handler supports it) on a per-request basis via the `future`
294parameter in the client options:
295
296[source,php]
297----
298$client = ClientBuilder::create()->build();
299
300$params = [
301    'index'  => 'test',
302    'id'     => 1,
303    'client' => [
304        'future' => 'lazy'
305    ]
306];
307$future = $client->get($params);
308$results = $future->wait();       // resolve the future
309----
310
311Future mode supports two options: `true` or `'lazy'`. For more details about how
312asynchronous execution functions, and how to work with the results, see the
313dedicated page on <<future_mode>>.
314
315
316==== SSL Encryption
317
318Normally, you specify SSL configurations when you create the client (see
319<<authentication>> for more details), since encryption typically applies to all
320requests. However, it is possible to configure on a per-request basis, too, if
321you need that functionality. For example, if you need to use a self-signed cert
322on a specific request, you can specify it via the `verify` parameter in the
323client options:
324
325[source,php]
326----
327$client = ClientBuilder::create()->build();
328
329$params = [
330    'index'  => 'test',
331    'id'     => 1,
332    'client' => [
333        'verify' => 'path/to/cacert.pem'      //Use a self-signed certificate
334    ]
335];
336$result = $client->get($params);
337----
338