craftcms / element-api

Create a JSON API/Feed for your elements in Craft.
MIT License
498 stars 57 forks source link

cache-control headers #111

Closed oddnavy closed 5 years ago

oddnavy commented 5 years ago

If we add headers via a TransformAbstract, these headers are lost from the request when the PHP cache is enabled in the element-api plugin. Assuming this could be due to the transformer not being called when the request is served from cache.

For example:

class PageTransformer extends TransformerAbstract
{
  public function transform(Entry $entry)
  {
    Craft::$app->response->headers->set('Access-Control-Allow-Origin', '*');
    Craft::$app->response->headers->set('Cache-Control', 's-maxage=30, stale-while-revalidate=86400, stale-if-error=86400');

    return [
      'title' => $entry->title,
      'url' => $entry->url,
    ];
  }
}

Has the following response headers:

Date: Sun, 28 Jul 2019 23:28:32 GMT
Server: Apache/2.4.25 (Debian)
X-Powered-By: Craft Commerce,Craft CMS
Access-Control-Allow-Origin: *
Cache-Control: s-maxage=30, stale-while-revalidate=86400, stale-if-error=86400
Content-Length: 4786
Content-Type: application/json; charset=UTF-8

But if we enable the cache flag in the element-api config:

    'api/pages/<id>' => function ($id) {
      return [
        'cache' => 'PT30S',
        'criteria' => ['id' => $id],
        'one' => true,
        'transformer' => new PageTransformer(),
      ];
    },

The response headers are:

Date: Sun, 28 Jul 2019 23:51:53 GMT
Server: Apache/2.4.25 (Debian)
X-Powered-By: Craft Commerce,Craft CMS
Content-Length: 4786
Content-Type: application/json; charset=UTF-8

How can we ensure cache headers are always set? We want to cache api requests at a CDN level too.

brandonkelly commented 5 years ago

Correct, transformers are only run when not pulling from cache.

Set the headers from your main endpoint config factory instead:

'api/pages/<id>' => function ($id) {
    Craft::$app->response->headers
        ->set('Access-Control-Allow-Origin', '*')
        ->set('Cache-Control', 's-maxage=30, stale-while-revalidate=86400, stale-if-error=86400');

    return [
        'cache' => 'PT30S',
        'criteria' => ['id' => $id],
        'one' => true,
        'transformer' => new PageTransformer(),
    ];
},
oddnavy commented 5 years ago

Thank you! This will be handy