- π¦πΊAustralia larowlan π¦πΊπ.au GMT+10
Is this a duplicate of π [pp-3] Bubbling of elements' max-age to the page's headers and the page cache Postponed ?
- Status changed to Closed: duplicate
10 months ago 12:13am 24 September 2024
We are using the JSON:API Resources module to define a custom JSON:API endpoint. We are setting the cacheability metadata on the resource being returned so that the max-age
is set to 0
. Despite this, when requests to the endpoint are accessed by anonymous users, the response is returned from the page cache unless we add the "no_cache"
option to the route in routing.yml
. Shouldn't the fact that the cacheability is set to a max age of 0
bubble-up to the page cache determination?
namespace Drupal\bug_repro\Resource;
use Drupal\Component\Datetime\TimeInterface;
use Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException;
use Drupal\Component\Plugin\Exception\PluginNotFoundException;
use Drupal\Core\Cache\CacheableMetadata;
use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
use Drupal\jsonapi\JsonApiResource\LinkCollection;
use Drupal\jsonapi\JsonApiResource\ResourceObject;
use Drupal\jsonapi\JsonApiResource\ResourceObjectData;
use Drupal\jsonapi\ResourceResponse;
use Drupal\jsonapi\ResourceType\ResourceType;
use Drupal\jsonapi_resources\Resource\ResourceBase;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Route;
class BugReproResource extends ResourceBase implements ContainerInjectionInterface {
/**
* The Drupal time service.
*
* @var \Drupal\Component\Datetime\TimeInterface
*/
protected $timeService;
/**
* {@inheritDoc}
*/
public static function create(ContainerInterface $container): BugReproResource {
return new static($container->get('datetime.time'));
}
/**
* Constructor for BugReproResource.
*
* @param \Drupal\Component\Datetime\TimeInterface $time_service
* The Drupal time service.
*/
public function __construct(TimeInterface $time_service) {
$this->timeService = $time_service;
}
/**
* Process an bug repro query.
*
* @param \Symfony\Component\HttpFoundation\Request $request
* The request.
*
* @return \Drupal\jsonapi\ResourceResponse
* The response.
*/
public function process(Request $request): ResourceResponse {
$resource_type = new ResourceType('bug_repro', 'bug_repro', NULL);
// Never cache.
$cacheability =
(new CacheableMetadata())
->setCacheMaxAge(0)
->addCacheContexts(['url.path', 'url.query_args']);
$attributes = ['timestamp' => $this->getTimeService()->getCurrentTime()];
$primary_data =
new ResourceObject(
$cacheability,
$resource_type,
'fake',
NULL,
$attributes,
new LinkCollection([])
);
$top_level_data = new ResourceObjectData([$primary_data], 1);
try {
$response = $this->createJsonapiResponse($top_level_data, $request);
}
catch (InvalidPluginDefinitionException | PluginNotFoundException $ex) {
throw new \RuntimeException(
'Failed to create JSON:API response: ' . $ex->getMessage(),
0,
$ex
);
}
$response->addCacheableDependency($cacheability);
return $response;
}
/**
* Gets the Drupal time service.
*
* @return \Drupal\Component\Datetime\TimeInterface
* The interface for getting access to request time.
*/
protected function getTimeService(): TimeInterface {
return $this->timeService;
}
/**
* {@inheritdoc}
*/
public function getRouteResourceTypes(Route $route,
string $route_name): array {
$resource_type =
new ResourceType(
'bug_repro',
'bug_repro',
NULL,
FALSE,
TRUE,
FALSE,
FALSE,
[]
);
return [$resource_type];
}
}
bug_repro:
path: '/%jsonapi%/bug_repro'
defaults:
_jsonapi_resource: '\Drupal\example\Resource\BugReproResource'
requirements:
_access: 'TRUE'
/jsonapi/bug_repro
.timestamp
attribute returned in the resource.no_cache
option, like so:bug_repro:
path: '/%jsonapi%/bug_repro'
defaults:
_jsonapi_resource: '\Drupal\example\Resource\BugReproResource'
requirements:
_access: 'TRUE'
options:
no_cache: TRUE
/jsonapi/bug_repro
.timestamp
attribute returned in the resource.You will notice that the timestamp does not increment unless the route is set not to cache, even though the cacheability of the response is set to not cache.
If any element of a page indicates a cache max age of 0
, the page should not be cacheable.
Either:
\Drupal\Core\EventSubscriber\FinishResponseSubscriber::onRespond()
to properly detect bubbling of cacheability from page content.Postponed: needs info
11.0 π₯
Last updated
Not all content is available!
It's likely this issue predates Contrib.social: some issue and comment data are missing.
Is this a duplicate of π [pp-3] Bubbling of elements' max-age to the page's headers and the page cache Postponed ?