New in Symfony 6.3: HttpClient Improvements


Added JsonMockResponse

Contributed by Thomas Calvet
in #50044.

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:

// 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

Contributed by Roman Andreev
in #48797.

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:

// 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

Contributed by Nicolas Grekas
in #50274.

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

Contributed by Benjamin Zaslavsky
in #49809.

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:

$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

Contributed by Nicolas Grekas
in #49911.

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:

$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:

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

Contributed by Thomas Calvet
in #49302.

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():

$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:

# config/packages/framework.yaml
framework:
http_client:
default_options:
vars:
- secret: 'secret-token'

Sponsor the Symfony project.