@@ -6,12 +6,18 @@ The HttpClient Component
66========================
77
88 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.
1011
1112.. versionadded :: 4.3
1213
1314 The HttpClient component was introduced in Symfony 4.3.
1415
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+
1521 Installation
1622------------
1723
@@ -69,14 +75,15 @@ Enabling HTTP/2 Support
6975-----------------------
7076
7177HTTP/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::
7481
7582 $httpClient = HttpClient::create(['http_version' => '2.0']);
7683
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 .
8087
8188Making Requests
8289---------------
@@ -89,14 +96,13 @@ method to perform all kinds of HTTP requests::
8996 $response = $httpClient->request('PUT', 'https://...');
9097 // ...
9198
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::
95101
102+ // code execution continues immediately; it doesn't wait to receive the response
96103 $response = $httpClient->request('GET', 'http://releases.ubuntu.com/18.04.2/ubuntu-18.04.2-desktop-amd64.iso');
97104
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
100106 $contentType = $response->getHeaders()['content-type'][0];
101107
102108 // trying to get the response contents will block the execution until
@@ -135,8 +141,8 @@ each request (which overrides any global authentication)::
135141Query String Parameters
136142~~~~~~~~~~~~~~~~~~~~~~~
137143
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 define them as an
145+ associative array via the ``query `` option, that will be merged with the URL ::
140146
141147 // it makes an HTTP GET request to https://httpbin.org/get?token=...&name=...
142148 $response = $httpClient->request('GET', 'https://httpbin.org/get', [
@@ -155,7 +161,7 @@ requests and the specific headers for each request::
155161
156162 // this header is added to all requests made by this client
157163 $httpClient = HttpClient::create(['headers' => [
158- 'Accept-Encoding ' => 'gzip ',
164+ 'User-Agent ' => 'My Fancy App ',
159165 ]]);
160166
161167 // this header is only included in this request and overrides the value
@@ -170,7 +176,7 @@ Uploading Data
170176~~~~~~~~~~~~~~
171177
172178This 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
174180processed automatically when making the requests::
175181
176182 $response = $httpClient->request('POST', 'https://...', [
@@ -264,7 +270,7 @@ following methods::
264270Streaming Responses
265271~~~~~~~~~~~~~~~~~~~
266272
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
268274response sequentially instead of waiting for the entire response::
269275
270276 $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::
286292 // response chunks implement Symfony\Contracts\HttpClient\ChunkInterface
287293 $fileHandler = fopen('/ubuntu.iso', 'w');
288294 foreach ($httpClient->stream($response) as $chunk) {
289- fwrite($fileHandler, $chunk->getContent(); );
295+ fwrite($fileHandler, $chunk->getContent());
290296 }
291297
292298Handling Exceptions
293299~~~~~~~~~~~~~~~~~~~
294300
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 in the 300-599 range (i.e. 3xx,
2963024xx or 5xx) your code is expected to handle it. If you don't do that, the
297303``getHeaders() `` and ``getContent() `` methods throw an appropriate exception::
298304
@@ -335,19 +341,15 @@ class to autoconfigure the HTTP client based on the requested URL::
335341 use Symfony\Component\HttpClient\ScopingHttpClient;
336342
337343 $client = HttpClient::create();
338- $httpClient = new ScopingHttpClient($client, [
339- // the key is a regexp which must match the beginning of the request URL
344+ $client = new ScopingHttpClient($client, [
345+ // the options defined as values apply only to the URLs matching
346+ // the regular expressions defined as keys
340347 'https://api\.github\.com/' => [
341348 'headers' => [
342349 'Accept' => 'application/vnd.github.v3+json',
343350 'Authorization' => 'token '.$githubToken,
344351 ],
345352 ],
346-
347- // use a '*' wildcard to apply some options to all requests
348- '*' => [
349- // ...
350- ]
351353 ]);
352354
353355If the request URL is relative (because you use the ``base_uri `` option), the
@@ -362,30 +364,25 @@ regular expression applied to relative URLs::
362364 'base_uri' => 'https://api.github.com/',
363365 // ...
364366 ],
365-
366- '*' => [
367- // ...
368- ]
369367 ],
370368 // this is the regexp applied to all relative URLs
371369 'https://api\.github\.com/'
372370 );
373371
374- PSR-7 and PSR- 18 Compatibility
375- ------------------------------
372+ PSR-18 Compatibility
373+ --------------------
376374
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 `
375+ This component uses and implements abstractions defined by the
376+ `` symfony/contracts `` package. It also implements the `PSR-18 `_ (HTTP Client)
377+ specifications via the :class: `Symfony\\ Component\\ HttpClient\\ Psr18Client `
380378class, which is an adapter to turn a Symfony ``HttpClientInterface `` into a
381379PSR-18 ``ClientInterface ``.
382380
383- Before using it in your application, run the following commands to install the
384- required dependencies:
381+ To use it, you need the ``psr/http-client `` package and a `PSR-17 `_ implementation:
385382
386383.. code-block :: terminal
387384
388- # installs the base ClientInterface
385+ # installs the PSR-18 ClientInterface
389386 $ composer require psr/http-client
390387
391388 # installs an efficient implementation of response and stream factories
@@ -437,12 +434,11 @@ If you want to define multiple HTTP clients, use this other expanded configurati
437434 framework :
438435 # ...
439436 http_client :
440- http_clients :
441- crawler :
437+ scoped_clients :
438+ crawler.client :
442439 headers : [{ 'X-Powered-By': 'ACME App' }]
443440 http_version : ' 1.0'
444- default :
445- max_host_connections : 10
441+ some_api.client :
446442 max_redirects : 7
447443
448444 Injecting the HTTP Client Into Services
@@ -533,5 +529,5 @@ However, using ``MockResponse`` allows simulating chunked responses and timeouts
533529 $mockResponse = new MockResponse($body());
534530
535531.. _`cURL PHP extension` : https://php.net/curl
536- .. _`PSR-7 ` : https://www.php-fig.org/psr/psr-7 /
532+ .. _`PSR-17 ` : https://www.php-fig.org/psr/psr-17 /
537533.. _`PSR-18` : https://www.php-fig.org/psr/psr-18/
0 commit comments