Symfony 8.2 Nouveauté Publié le

Un Cache-Control pour le CDN, un autre pour le navigateur

$response->cacheControl('CDN') écrit un CDN-Cache-Control : le CDN, qu'on sait purger, garde la page longtemps ; le navigateur, non.

Notions abordées : HttpFoundationCache HTTP

Nouveau dans Symfony 8.2 (en développement). Entre l'application et le lecteur, une réponse traverse plusieurs caches : un CDN, parfois un proxy, puis le navigateur. Tous lisent le même Cache-Control. Or ils ne se valent pas : le CDN, on sait le purger quand un article change ; le navigateur, jamais. Une page gardée une journée par le CDN l'était aussi par chaque navigateur, et un correctif publié à midi restait invisible à qui avait lu le matin.

Des en-têtes ciblés

La RFC 9213 permet d'écrire, à côté de Cache-Control, un en-tête destiné à un seul cache : CDN-Cache-Control pour les CDN, ou un nom propre au fournisseur. Le cache qui reconnaît son en-tête l'applique et ignore Cache-Control ; les autres l'ignorent. Symfony 8.2 les écrit pour vous :

$response->setMaxAge(0)->setPrivate();

$response->cacheControl('CDN')
    ->setMaxAge(3600)
    ->setStaleWhileRevalidate(60);
Cache-Control: max-age=0, private
CDN-Cache-Control: max-age=3600, stale-while-revalidate=60

stale-while-revalidate laisse le CDN servir la copie périmée pendant qu'il en redemande une fraîche ; stale-if-error la lui fait servir si l'application ne répond plus.

Et pour voir ce que fait le cache ?

La même version ajoute Cache-Status (RFC 9211) au cache HTTP de Symfony : framework.http_cache.cache_status: 'Symfony' fait dire à chaque réponse si elle vient du cache (Symfony; hit; ttl=58) ou de l'application (Symfony; fwd=miss; stored). Il n'entre pas dans cet exercice, mais c'est l'outil pour vérifier ce que vous allez écrire.

À faire

Dans JournalController :

  1. Un article : le CDN le garde une journée (86400), avec 60 s de stale-while-revalidate et une heure de stale-if-error. Le navigateur le revalide à chaque visite : max-age=0, private.
  2. La une : cinq minutes au CDN, une minute partout ailleurs (public).
  3. Le panier ne change pas : il ne concerne que le navigateur, et n'a rien à dire au CDN.

L'onglet « Requêtes » montre les en-têtes de chaque réponse.

D'où vient la fonctionnalité : la pull request d'origine.