Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
116 changes: 101 additions & 15 deletions http_client.rst
Original file line number Diff line number Diff line change
Expand Up @@ -740,6 +740,8 @@
'max_redirects' => 0,
]);

.. _http-client-retry-failed-requests:

Retry Failed Requests
~~~~~~~~~~~~~~~~~~~~~

Expand Down Expand Up @@ -1490,25 +1492,108 @@
------------------------------

This component provides a :class:`Symfony\\Component\\HttpClient\\CachingHttpClient`
decorator that allows caching responses and serving them from the local storage
for next requests. The implementation leverages the
:class:`Symfony\\Component\\HttpKernel\\HttpCache\\HttpCache` class under the hood
so that the :doc:`HttpKernel component </components/http_kernel>` needs to be
installed in your application::
decorator that allows caching responses and serving them from the cache storage
for next requests as described in `RFC 9111`_.

use Symfony\Component\HttpClient\CachingHttpClient;
use Symfony\Component\HttpClient\HttpClient;
use Symfony\Component\HttpKernel\HttpCache\Store;
The implementation leverages a
:class:`tag aware cache <Symfony\\Contracts\\Cache\\TagAwareCacheInterface>` under the hood
so the :doc:`Cache component </components/cache>` needs to be
installed in your application.

$store = new Store('/path/to/cache/storage/');
$client = HttpClient::create();
$client = new CachingHttpClient($client, $store);
.. tip::

The implementation is asynchronous, so the response must be consumed
(e.g., via getContent() or streaming) for caching to occur.

.. configuration-block::

.. code-block:: yaml

# config/packages/framework.yaml
framework:
http_client:
scoped_clients:
example.client:
base_uri: 'https://example.com'
caching:
cache_pool: example_cache_pool

cache:
pools:
example_cache_pool:
adapter: cache.adapter.redis_tag_aware
tags: true

.. code-block:: xml

<!-- config/packages/framework.xml -->
<?xml version="1.0" encoding="UTF-8" ?>
<container xmlns="http://symfony.com/schema/dic/services"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:framework="http://symfony.com/schema/dic/symfony"
xsi:schemaLocation="http://symfony.com/schema/dic/services
https://symfony.com/schema/dic/services/services-1.0.xsd
http://symfony.com/schema/dic/symfony https://symfony.com/schema/dic/symfony/symfony-1.0.xsd">

<framework:config>
<framework:http-client>
<framework:scoped-client name="example.client"
base-uri="https://example.com"
>
<framework:caching cache-pool="example_cache_pool"/>
</framework:scoped-client>
</framework:http-client>

<framework:cache>
<framework:pool name="example_cache_pool"
adapter="cache.adapter.redis_tag_aware"
tags="true"
/>
</framework:cache>
</framework:config>
</container>

.. code-block:: php

// config/packages/framework.php
use Symfony\Config\FrameworkConfig;

return static function (FrameworkConfig $framework): void {
$framework->httpClient()->scopedClient('example.client')
->baseUri('https://example.com')
->caching()
->cachePool('example_cache_pool')
// ...
;

$framework->cache()
->pool('example_cache_pool')
->adapter('cache.adapter.redis_tag_aware')
->tags(true)
;
};

Check failure on line 1574 in http_client.rst

View workflow job for this annotation

GitHub Actions / Code Blocks

[Cache Warmup] 2025-10-21T10:23:31+00:00 [critical] Uncaught Error: Call to undefined method Symfony\Config\Framework\Cache\PoolConfig::adapter()

.. code-block:: php-standalone

use Symfony\Component\Cache\Adapter\FilesystemTagAwareAdapter;
use Symfony\Component\HttpClient\CachingHttpClient;
use Symfony\Component\HttpClient\HttpClient;

$cache = new FilesystemTagAwareAdapter();

$client = HttpClient::createForBaseUri('https://example.com');
$cachingClient = new CachingHttpClient($client, $cache);

.. tip::

It is also highly recommended to configure a :ref:`retry strategy <http-client-retry-failed-requests>`
to gracefully handle cache inconsistency.

// this won't hit the network if the resource is already in the cache
$response = $client->request('GET', 'https://example.com/cacheable-resource');
.. versionadded:: 7.4

:class:`Symfony\\Component\\HttpClient\\CachingHttpClient` accepts a third argument
to set the options of the :class:`Symfony\\Component\\HttpKernel\\HttpCache\\HttpCache`.
Compliance with `RFC 9111`_ and leveraging the
:doc:`Cache component </components/cache>` was introduced in Symfony 7.4.
Prior to this, it used ``HttpCache`` from the HttpKernel component.

Limit the Number of Requests
----------------------------
Expand Down Expand Up @@ -2494,5 +2579,6 @@
.. _`idempotent method`: https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Idempotent_methods
.. _`SSRF`: https://portswigger.net/web-security/ssrf
.. _`RFC 6570`: https://www.rfc-editor.org/rfc/rfc6570
.. _`RFC 9111`: https://www.rfc-editor.org/rfc/rfc9111
.. _`HAR`: https://w3c.github.io/web-performance/specs/HAR/Overview.html
.. _`the Cookie HTTP request header`: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cookie
71 changes: 71 additions & 0 deletions reference/configuration/framework.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1661,6 +1661,77 @@
returned value is ``true`` (the closure receives as argument an array with the
response headers).

caching
.......

**type**: ``array``

This option configures the behavior of the HTTP client caching, including which
types of requests to cache and how many times. The behavior is
defined with the following options:

* :ref:`cache_pool <reference-http-client-caching-cache-pool>`
* :ref:`shared <reference-http-client-caching-shared>`
* :ref:`max_ttl <reference-http-client-caching-max-ttl>`

.. code-block:: yaml

# config/packages/framework.yaml
framework:
# ...
http_client:
# ...
default_options:
caching:
cache_pool: cache.app
shared: true
max_ttl: 86400

scoped_clients:
my_api.client:
# ...
caching:
cache_pool: my_taggable_pool

Check failure on line 1694 in reference/configuration/framework.rst

View workflow job for this annotation

GitHub Actions / Code Blocks

[Cache Warmup] In BaseNode.php line 432: Invalid configuration for path "framework.http_client.scoped_clients.my_api .client": Either "scope" or "base_uri" should be defined. In ExprBuilder.php line 220: Either "scope" or "base_uri" should be defined.

.. versionadded:: 7.4

The ``caching`` option was introduced in Symfony 7.4.

.. _reference-http-client-caching-cache-pool:

cache_pool
""""""""""

**type**: ``string``

The service ID of the cache pool used to store the cached responses. The service
must implement the :class:`Symfony\\Contracts\\Cache\\TagAwareCacheInterface`.

By default, it uses an instance of :class:`Symfony\\Component\\Cache\\Adapter\\TagAwareAdapter`
wrapping the ``cache.app`` pool.

.. _reference-http-client-caching-shared:

shared
"""""""

**type**: ``boolean`` **default**: ``true``

Whether the cache is shared or private. If ``true``, the cache
is `shared <https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/Caching#shared_cache>`_
(default), if ``false``, the cache is
`private <https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/Caching#private_caches>`_.

.. _reference-http-client-caching-max-ttl:

max_ttl
"""""""""

**type**: ``integer`` **default**: ``null``

The maximum time-to-live (in seconds) for cached responses. Server-provided TTLs
are capped to this value if set.

cafile
......

Expand Down
Loading