craftcms / element-api

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

Busting cache on endpoint/element changes #47

Closed AwakenTheJaken closed 7 years ago

AwakenTheJaken commented 7 years ago

Is there any way to turn caching on, but bust the cache when that endpoint/element changes through the cms? At the moment the caching is working great, but I have to manually bust the cache any time anything on the cms side changes. Is this the expected behavior and if not -- am I missing something here?

'api/v2/faqs.json' => [
    'cache' => 'PT1M',
    'elementType' => 'Entry',
    'criteria' => [
        'section' => 'faq'
    ],
    'transformer' => function(EntryModel $entry) {
        $categories = [];
        foreach($entry->faqCategory as $category){
          $categories[] = $category->id;
        }
        return [
            'title' => $entry->title,
            'answer' => (string)$entry->answer,
            'categories' => $categories,
        ];
    },
],

Thanks so much for the absolutely AWESOME plugin.

AwakenTheJaken commented 7 years ago

Okay, so a bit of an update on this. I was able to accomplish this by busting the cache using a custom (simple) plugin init function that listens for the elements.onSaveElement event, which then calls craft()->cache->flush(); as seen below.

craft()->on('elements.onSaveElement', function(Event $event) {
          craft()->cache->flush();
});

This works great, however there is no way of checking if the status changes / entry expires via the TasksService. I have tried a few things including checking the actions with elements.onPerformAction, but with no success, see below.

craft()->on('elements.onPerformAction', function(Event $event) {
          $action = $event->params['action']->classHandle;

          if($action == 'SetStatus'){
            craft()->cache->flush();
          }

});

Any help or guidance on how to hook into the TasksService event for this would be greatly appreciated!

Hnto commented 7 years ago

Hey @AwakenTheJaken,

I've had the same problem and I thought it would be helpful if I created a plugin for this. You can download the plugin at the craftcms plugin page.

https://straightupcraft.com/craft-plugins/cache-buster-for-elementapi

Greets, Hnto

AwakenTheJaken commented 7 years ago

Hey thanks for the reply, however I built pretty much the same thing to solve the issue. This approach works fine, but falls short when items need to be expired ( EG: a Promotions page). :-1: Looks like there is no way of doing this unless you want to hack the core files. The cache itself doesn't care for expiration dates of individual entries, just what you feed it. Hope this helps someone going down the same path.

jamealg commented 6 years ago

There is a Craft 3 plugin which will trigger events when entries are published at a future date. I haven't attempted to implement it yet and there is no documentation but it's worth looking into. It's also in their roadmap to add events for expired entries.

https://github.com/sjelfull/craft3-publishedevent