0

I'm trying to create a REST API get response. My class extends ResourceBase and this is inside my classes get function.

$response = new ResourceResponse(['time' => time()], 200);

$cache_meta_data = new CacheableMetadata();
$cache_meta_data->setCacheMaxAge(2);
$response->addCacheableDependency($page);
$response->addCacheableDependency($cache_meta_data);

return $response;

This will return the timestamp, but it will be cached forever until I manually clear the Drupal cache. When I curl the interface this is the output for the first hit.

curl 'https://mylocaldrupal.dd:8443/rest/upcoming_matches/1?_format=json' -i -k
HTTP/1.1 200 OK
Date: Sun, 11 Feb 2018 17:03:06 GMT
Server: Apache/2.4.17 (Unix) OpenSSL/1.0.1h mod_fcgid/2.3.9
X-Powered-By: PHP/7.0.14
Cache-Control: must-revalidate, no-cache, private
X-Drupal-Dynamic-Cache: UNCACHEABLE
X-UA-Compatible: IE=edge
Content-language: en
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
Expires: Sun, 19 Nov 1978 05:00:00 GMT
X-Generator: Drupal 8 (https://www.drupal.org)
X-Drupal-Cache: MISS
Transfer-Encoding: chunked
Content-Type: application/json

{"time":1518368586}

And a second hit after a few seconds:

curl 'https://mylocaldrupal.dd:8443/rest/upcoming_matches/1?_format=json' -i -k
HTTP/1.1 200 OK
Date: Sun, 11 Feb 2018 17:04:41 GMT
Server: Apache/2.4.17 (Unix) OpenSSL/1.0.1h mod_fcgid/2.3.9
X-Powered-By: PHP/7.0.14
Cache-Control: must-revalidate, no-cache, private
X-Drupal-Dynamic-Cache: UNCACHEABLE
X-UA-Compatible: IE=edge
Content-language: en
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
Expires: Sun, 19 Nov 1978 05:00:00 GMT
X-Generator: Drupal 8 (https://www.drupal.org)
X-Drupal-Cache: HIT
Transfer-Encoding: chunked
Content-Type: application/json

{"time":1518368586}

Can't really figure it out and the Drupal.org docs doesn't really seem to help me neither. Am I missing something obvious?

1

The referenced question from 4k4 describes how to disable the internal page cache completely.

To not disable but set an expiration on the anonymous/internal page cache, you can use the Expires header, just set it to a date in the future and that will be respected. That's the only thing that the internal page cache module currently respects.

See the linked core issue for more information, it's partially simply an overlook that it wasn't done before 8.0 but now it would be an API change to start respecting it and lots of things would then make Drupal uncacheable, like the language switcher block. So we'll have to be very careful with any change we make.

  • Thank you for pointing out that indeed MaxAge is ignored. I also found the referenced issue on DO. Do you have an example on how to set the Expires header? I tried to do it but somehow it always get overridden with the 19 nov 1978 date. – Bram Feb 12 '18 at 9:05
  • 1
    This is what we do in a response event subscriber, should also work directly in the controller IMHO, FinishResponseSubcriber should only set a custom expires header if none is set yet: $response->setExpires(new \DateTime($cache_max_age . 'sec')); – Berdir Feb 12 '18 at 9:24
  • I tried this event subscriber approach and the Expires header is correct. However the data itself seems to be cached forever. Do I need to change the Cache-Control headers as well (see original question above) – Bram Feb 12 '18 at 11:38

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.