@@ -6,12 +6,18 @@ The HttpClient Component
6
6
========================
7
7
8
8
The HttpClient component is a low-level HTTP client with support for both
9
- PHP stream wrappers and cURL. It also provides utilities to consume APIs.
9
+ PHP stream wrappers and cURL. It provides utilities to consume APIs and
10
+ supports synchronous and asynchronous operations.
10
11
11
12
.. versionadded :: 4.3
12
13
13
14
The HttpClient component was introduced in Symfony 4.3.
14
15
16
+ .. TODO
17
+ .. tell about implementation vs abstraction
18
+ .. tell there are more options
19
+ .. tell chunked + compression are supported out of the box
20
+
15
21
Installation
16
22
------------
17
23
@@ -69,14 +75,15 @@ Enabling HTTP/2 Support
69
75
-----------------------
70
76
71
77
HTTP/2 is only supported when using the cURL-based transport and the libcurl
72
- version is >= 7.36.0. If you meet these requirements, you can enable HTTP/2
73
- explicitly via the ``http_version `` option::
78
+ version is >= 7.36.0. If you meet these requirements, HTTP/2 will be used by
79
+ default when the request protocol is ``https ``. If you need it for ``http ``,
80
+ you must enable it explicitly via the ``http_version `` option::
74
81
75
82
$httpClient = HttpClient::create(['http_version' => '2.0']);
76
83
77
- If you don't set the HTTP version explicitly, Symfony will use `` '2.0' `` only
78
- when the request protocol is `` https:// `` (and the cURL requirements mentioned
79
- earlier are met) .
84
+ Support for HTTP/2 PUSH works out of the box when libcurl >= 7.61.0 is used with
85
+ PHP >= 7.2.17 / 7.3.4: pushed responses are put into a temporary cache and are
86
+ used when a subsequent request is triggered for the corresponding URLs .
80
87
81
88
Making Requests
82
89
---------------
@@ -89,14 +96,13 @@ method to perform all kinds of HTTP requests::
89
96
$response = $httpClient->request('PUT', 'https://...');
90
97
// ...
91
98
92
- Responses are always asynchronous, so they are ready as soon as the response
93
- HTTP headers are received, instead of waiting to receive the entire response
94
- contents::
99
+ Responses are always asynchronous, so that the call to the method returns
100
+ immediately instead of waiting to receive the response::
95
101
102
+ // code execution continues immediately; it doesn't wait to receive the response
96
103
$response = $httpClient->request('GET', 'http://releases.ubuntu.com/18.04.2/ubuntu-18.04.2-desktop-amd64.iso');
97
104
98
- // code execution continues immediately; it doesn't wait to receive the response
99
- // you can get the value of any HTTP response header
105
+ // getting the response headers waits until they arrive
100
106
$contentType = $response->getHeaders()['content-type'][0];
101
107
102
108
// trying to get the response contents will block the execution until
@@ -135,8 +141,8 @@ each request (which overrides any global authentication)::
135
141
Query String Parameters
136
142
~~~~~~~~~~~~~~~~~~~~~~~
137
143
138
- You can either append them manually to the requested URL, or better, add them
139
- as an associative array to the ``query `` option::
144
+ You can either append them manually to the requested URL, or add them as an
145
+ associative array to the ``query `` option that will be merged with the URL ::
140
146
141
147
// it makes an HTTP GET request to https://httpbin.org/get?token=...&name=...
142
148
$response = $httpClient->request('GET', 'https://httpbin.org/get', [
@@ -155,7 +161,7 @@ requests and the specific headers for each request::
155
161
156
162
// this header is added to all requests made by this client
157
163
$httpClient = HttpClient::create(['headers' => [
158
- 'Accept-Encoding ' => 'gzip ',
164
+ 'User-Agent ' => 'My Fancy App ',
159
165
]]);
160
166
161
167
// this header is only included in this request and overrides the value
@@ -170,7 +176,7 @@ Uploading Data
170
176
~~~~~~~~~~~~~~
171
177
172
178
This component provides several methods for uploading data using the ``body ``
173
- option. You can use regular strings, closures and resources and they'll be
179
+ option. You can use regular strings, closures, iterables and resources and they'll be
174
180
processed automatically when making the requests::
175
181
176
182
$response = $httpClient->request('POST', 'https://...', [
@@ -264,7 +270,7 @@ following methods::
264
270
Streaming Responses
265
271
~~~~~~~~~~~~~~~~~~~
266
272
267
- Call to the ``stream() `` method of the HTTP client to get *chunks * of the
273
+ Call the ``stream() `` method of the HTTP client to get *chunks * of the
268
274
response sequentially instead of waiting for the entire response::
269
275
270
276
$url = 'https://releases.ubuntu.com/18.04.1/ubuntu-18.04.1-desktop-amd64.iso';
@@ -286,13 +292,13 @@ response sequentially instead of waiting for the entire response::
286
292
// response chunks implement Symfony\Contracts\HttpClient\ChunkInterface
287
293
$fileHandler = fopen('/ubuntu.iso', 'w');
288
294
foreach ($httpClient->stream($response) as $chunk) {
289
- fwrite($fileHandler, $chunk->getContent(); );
295
+ fwrite($fileHandler, $chunk->getContent());
290
296
}
291
297
292
298
Handling Exceptions
293
299
~~~~~~~~~~~~~~~~~~~
294
300
295
- When the HTTP status code of the response is not in the 200 -299 range (i.e. 3xx,
301
+ When the HTTP status code of the response is not in the 100 -299 range (i.e. 3xx,
296
302
4xx or 5xx) your code is expected to handle it. If you don't do that, the
297
303
``getHeaders() `` and ``getContent() `` methods throw an appropriate exception::
298
304
@@ -318,7 +324,8 @@ installed in your application.
318
324
319
325
..
320
326
.. TODO:
321
- .. Show some example of caching requests+responses
327
+ .. Show some example of caching requests+responses - should be move in a dedicated page?
328
+ .. move to a dedicated page?
322
329
..
323
330
..
324
331
@@ -335,19 +342,15 @@ class to autoconfigure the HTTP client based on the requested URL::
335
342
use Symfony\Component\HttpClient\ScopingHttpClient;
336
343
337
344
$client = HttpClient::create();
338
- $httpClient = new ScopingHttpClient($client, [
339
- // the key is a regexp which must match the beginning of the request URL
345
+ $client = new ScopingHttpClient($client, [
346
+ // the options definesd as values apply only to the URLs matching
347
+ // the regular expressions defined as keys
340
348
'https://api\.github\.com/' => [
341
349
'headers' => [
342
350
'Accept' => 'application/vnd.github.v3+json',
343
351
'Authorization' => 'token '.$githubToken,
344
352
],
345
353
],
346
-
347
- // use a '*' wildcard to apply some options to all requests
348
- '*' => [
349
- // ...
350
- ]
351
354
]);
352
355
353
356
If the request URL is relative (because you use the ``base_uri `` option), the
@@ -362,30 +365,26 @@ regular expression applied to relative URLs::
362
365
'base_uri' => 'https://api.github.com/',
363
366
// ...
364
367
],
365
-
366
- '*' => [
367
- // ...
368
- ]
369
368
],
370
369
// this is the regexp applied to all relative URLs
371
370
'https://api\.github\.com/'
372
371
);
373
372
374
- PSR-7 and PSR- 18 Compatibility
375
- ------------------------------
373
+ PSR-18 Compatibility
374
+ --------------------
376
375
377
- This component uses its own interfaces and exception classes different from the
378
- ones defined in ` PSR-7 `_ (HTTP message interfaces) and `PSR-18 `_ (HTTP Client).
379
- However, it includes the :class: `Symfony\\ Component\\ HttpClient\\ Psr18Client `
376
+ This component uses and implements abstractions defined by the
377
+ `` symfony/contracts `` package. It also implements the `PSR-18 `_ (HTTP Client)
378
+ specifications via the :class: `Symfony\\ Component\\ HttpClient\\ Psr18Client `
380
379
class, which is an adapter to turn a Symfony ``HttpClientInterface `` into a
381
380
PSR-18 ``ClientInterface ``.
382
381
383
- Before using it in your application, run the following commands to install the
384
- required dependencies :
382
+ To use it, you the `` psr/http-client `` package and use a ` PSR-17 `_
383
+ implementations :
385
384
386
385
.. code-block :: terminal
387
386
388
- # installs the base ClientInterface
387
+ # installs the PSR-18 ClientInterface
389
388
$ composer require psr/http-client
390
389
391
390
# installs an efficient implementation of response and stream factories
@@ -437,12 +436,11 @@ If you want to define multiple HTTP clients, use this other expanded configurati
437
436
framework :
438
437
# ...
439
438
http_client :
440
- http_clients :
441
- crawler :
439
+ scoped_clients :
440
+ crawler.client :
442
441
headers : [{ 'X-Powered-By': 'ACME App' }]
443
442
http_version : ' 1.0'
444
- default :
445
- max_host_connections : 10
443
+ some_api.client :
446
444
max_redirects : 7
447
445
448
446
Injecting the HTTP Client Into Services
@@ -481,6 +479,8 @@ has a unique service named after its configuration.
481
479
App\Some\Service :
482
480
$someArgument : ' @http_client.crawler'
483
481
482
+ .. TODO tell about named autowiring aliases
483
+
484
484
Testing HTTP Clients and Responses
485
485
----------------------------------
486
486
@@ -533,5 +533,5 @@ However, using ``MockResponse`` allows simulating chunked responses and timeouts
533
533
$mockResponse = new MockResponse($body());
534
534
535
535
.. _`cURL PHP extension` : https://php.net/curl
536
- .. _`PSR-7 ` : https://www.php-fig.org/psr/psr-7 /
536
+ .. _`PSR-17 ` : https://www.php-fig.org/psr/psr-17 /
537
537
.. _`PSR-18` : https://www.php-fig.org/psr/psr-18/
0 commit comments