Magento 2 comes stock with a full page caching feature. However, it's not clear how the framework determines which URL end-points need to be cached. For example, if I create a simple controller that acts as a JSON endpoint
$data = ...;
$result = $this->resultJsonFactory->create();
return $result->setData($data);
The system seems smart enough to know not to cache this.
curl -I 'http://magento2.example.com/my/custom/endpoint'
//...
X-Magento-Cache-Debug: MISS
I've been able to track the built in caching functionality to this method (used by the built-in plugin)
#File: lib/internal/Magento/Framework/App/PageCache/Kernel.php
public function process(\Magento\Framework\App\Response\Http $response)
{
if (preg_match('/public.*s-maxage=(\d+)/', $response->getHeader('Cache-Control')->getFieldValue(), $matches)) {
$maxAge = $matches[1];
$response->setNoCacheHeaders();
if ($response->getHttpResponseCode() == 200 && ($this->request->isGet() || $this->request->isHead())) {
$tagsHeader = $response->getHeader('X-Magento-Tags');
$tags = $tagsHeader ? explode(',', $tagsHeader->getFieldValue()) : [];
$response->clearHeader('Set-Cookie');
$response->clearHeader('X-Magento-Tags');
if (!headers_sent()) {
header_remove('Set-Cookie');
}
$this->cache->save(serialize($response), $this->identifier->getValue(), $tags, $maxAge);
}
}
}
Which seems to examine the response object, and only cache requests if they're a HTTP 200
, either a GET
or HEAD
request. It also uses the Max-Age Cache-Control
header to ensure values are saved in the cache for an appropriate amount of time.
So, it's clear from this code that something instructs the system (i.e. sets cache headers on the response) to cache the request. What's not clear is where this happens during Magento's request flow, and which requests gets full page caching and which do not.
X-Magento-Cache-Debug
is alwaysMISS
. Any idea what it could be?