New in Symfony 6.3: HttpClient Improvements
May 15, 2023 • Published by Javier Eguiluz
Symfony 6.3 is backed by:
Warning: This post is about an unsupported Symfony version. Some of this information may be out of date. Read the most recent Symfony Docs.
Added JsonMockResponse
The HttpClient component provides some utilities to test HTTP requests and responses
using a MockHttpClient
that returns MockResponse
objects. In Symfony 6.3
we've introduced the JsonMockResponse
utility class to mock JSON responses:
1 2 3 4 5 6 7 8 9 10 11 12
// BEFORE
use Symfony\Component\HttpClient\Response\MockResponse;
new MockResponse(
json_encode(['foo' => 'bar']),
['response_headers' => ['content-type' => 'application/json']]
);
// AFTER
use Symfony\Component\HttpClient\Response\JsonMockResponse;
new JsonMockResponse(['foo' => 'bar']);
Configure Extra Options
The extra
option passed to the request()
method of the HttpClient component
allows to define additional configuration, such as cURL options. In Symfony 6.3
you can also define those extra
options when configuring the HttpClient.
This way, you can configure cURL options such as certificates once and use them in all requests made with that HTTP client:
1 2 3 4 5 6 7 8 9 10 11 12 13
// this example shows how to configure these options when using
// PHP config format; but it also works with YAML and XML
return static function (FrameworkConfig $frameworkConfig): void {
$httpClient = $frameworkConfig->httpClient();
$httpClient->defaultOptions([
'extra' => ['curl' => ['foo' => 'bar']]
]);
$httpClient->scopedClient('some_client')
->baseUri('https://some.uri')
->header('Accept', 'application/json')
->extra(['curl' => ['foo' => 'bar']]);
}
TLS v1.2 by default
In Symfony 6.3 we've added a new crypto_method
option to the
HttpClientInterface
so you can define the minimum TLS version to accept
when making requests. We've also set its default value to the PHP constant
STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT
, which corresponds to TLS v1.2.
This makes the client more secure by default. (Note that TLS v1.2 is available since 2008 and that all major browsers disabled support for TLS < 1.2 in 2020.)
Multiple Retry URIs
Retrying failed requests is one of the features that provides the HttpClient component to handle failed requests due to network issues or temporary server errors. In Symfony 6.3 we've improved this feature to allow defining multiple base URIs that are selected alternatively when retrying the requests:
1 2 3 4 5 6
$response = $client->request('GET', 'foo-bar', [
'base_uri' => [
'http://a.example.com/', // first request will use this base URI
'http://b.example.com/', // if first request fails, the second base URI will be used
],
]);
File Upload Improvements
When uploading data with the HttpClient component, the data is encoded by
default as application/x-www-form-urlencoded
. If you wanted to submit a form
with file uploads, it was your responsibility to encode the body according to
the multipart/form-data
content-type.
In Symfony 6.3 we've improved this situation and now you can upload one or more
files using multipart/form-data
as follows:
1 2
$fileHandle = fopen('/path/to/the/file' 'r');
$client->request('POST', 'https://...', ['body' => ['the_file' => $fileHandle]]);
By default, this code will populate the filename and content-type with the data of the opened file, but you can configure both with the PHP streaming configuration:
1 2
stream_context_set_option($fileHandle, 'http', 'filename', 'the-name.txt');
stream_context_set_option($fileHandle, 'http', 'content_type', 'my/content-type')
Add Support for URI Templates
URI templates, defined in the RFC 6570, describe a range of URLs via some
variable parts. For example, http://example.com/{username}/
uses a variable
in the URL path and http://example.com/search{?q,lang}
uses two variables
in the query string part of the URL.
In Symfony 6.3 you can use these URI templates with a new UriTemplateHttpClient()
:
1 2 3 4 5 6 7 8 9
$client = new UriTemplateHttpClient();
// This request will result on querying http://example.org/users?page=1
$client->request('GET', 'http://example.org/{resource}{?page}', [
'vars' => [
'resource' => 'users',
'page' => 1,
],
]);
You can even configure variables that will be replaced globally in all URI templates of your application:
1 2 3 4 5 6
# config/packages/framework.yaml
framework:
http_client:
default_options:
vars:
- secret: 'secret-token'
Help the Symfony project!
As with any Open-Source project, contributing code or documentation is the most common way to help, but we also have a wide range of sponsoring opportunities.
Comments are closed.
To ensure that comments stay relevant, they are closed for old posts.
Great addition, thank you ! How can we send multiple files with the HTTP client ? As for now, it seems that passing an array of files in the body results in no files at all being sent.