Skip to content

Commit

Permalink
Use element cache tags for cache invalidation
Browse files Browse the repository at this point in the history
Resolves #136
Resolves #123
  • Loading branch information
brandonkelly committed May 26, 2021
1 parent 4c2088c commit 4c08623
Show file tree
Hide file tree
Showing 5 changed files with 32 additions and 6 deletions.
10 changes: 10 additions & 0 deletions CHANGELOG.md
@@ -1,5 +1,15 @@
# Release Notes for Element API

## 2.7.0 - 2021-05-26
## Unreleased

### Added
- It’s now possible to invalidate Element API caches via the Caches utility and the `invalidate-tags/element-api` command. ([#136](https://github.com/craftcms/element-api/issues/136))

### Changed
- Element API now requires Craft CMS 3.5 or later.
- Endpoint responses are now cached by default, and are invalidated automatically when relevant elements are saved or deleted.

## 2.6.0 - 2019-08-01

### Added
Expand Down
2 changes: 1 addition & 1 deletion README.md
Expand Up @@ -7,7 +7,7 @@ It’s powered by Phil Sturgeon’s excellent [Fractal](http://fractal.thephplea

## Requirements

This plugin requires Craft CMS 3.0.0-RC16 or later.
This plugin requires Craft CMS 3.5 or later.


## Installation
Expand Down
2 changes: 1 addition & 1 deletion composer.json
Expand Up @@ -25,7 +25,7 @@
"rss": "https://github.com/craftcms/element-api/commits/v2.atom"
},
"require": {
"craftcms/cms": "^3.0.0-RC16",
"craftcms/cms": "^3.5.0",
"league/fractal": "^0.18.0"
},
"autoload": {
Expand Down
8 changes: 8 additions & 0 deletions src/Plugin.php
Expand Up @@ -4,7 +4,9 @@

use Craft;
use craft\elementapi\resources\ElementResource;
use craft\events\RegisterCacheOptionsEvent;
use craft\events\RegisterUrlRulesEvent;
use craft\utilities\ClearCaches;
use craft\web\UrlManager;
use League\Fractal\Resource\ResourceInterface;
use yii\base\Event;
Expand Down Expand Up @@ -39,6 +41,12 @@ public function init()
parent::init();

Event::on(UrlManager::class, UrlManager::EVENT_REGISTER_SITE_URL_RULES, [$this, 'registerUrlRules']);
Event::on(ClearCaches::class, ClearCaches::EVENT_REGISTER_TAG_OPTIONS, function(RegisterCacheOptionsEvent $event) {
$event->options[] = [
'tag' => 'element-api',
'label' => Craft::t('element-api', 'Element API responses'),
];
});
}

/**
Expand Down
16 changes: 12 additions & 4 deletions src/controllers/DefaultController.php
Expand Up @@ -15,13 +15,15 @@
use craft\elementapi\Plugin;
use craft\helpers\ArrayHelper;
use craft\helpers\ConfigHelper;
use craft\helpers\StringHelper;
use craft\web\Controller;
use League\Fractal\Manager;
use League\Fractal\Serializer\ArraySerializer;
use League\Fractal\Serializer\DataArraySerializer;
use League\Fractal\Serializer\JsonApiSerializer;
use League\Fractal\Serializer\SerializerAbstract;
use ReflectionFunction;
use yii\base\BaseObject;
use yii\base\InvalidConfigException;
use yii\web\HttpException;
use yii\web\JsonResponseFormatter;
Expand Down Expand Up @@ -70,7 +72,7 @@ public function actionIndex(string $pattern): Response
$callback = null;
$jsonOptions = null;
$pretty = false;
$cache = false;
$cache = true;
$statusCode = 200;
$statusText = null;

Expand All @@ -91,13 +93,14 @@ public function actionIndex(string $pattern): Response
}

// Before anything else, check the cache
$cache = ArrayHelper::remove($config, 'cache', false);
$cache = ArrayHelper::remove($config, 'cache', true);

if ($cache) {
$cacheKey = 'elementapi:'.$siteId.':'.$request->getPathInfo().':'.$request->getQueryStringWithoutPath();
$cacheService = Craft::$app->getCache();

if (($cachedContent = $cacheService->get($cacheKey)) !== false) {
Craft::dd($cachedContent);
// Set the JSON headers
(new JsonResponseFormatter())->format($response);

Expand All @@ -106,6 +109,9 @@ public function actionIndex(string $pattern): Response
$response->content = $cachedContent;
return $response;
}

$elementsService = Craft::$app->getElements();
$elementsService->startCollectingCacheTags();
}

// Extract config settings that aren't meant for createResource()
Expand Down Expand Up @@ -201,8 +207,10 @@ public function actionIndex(string $pattern): Response
} else {
$expire = null;
}
/** @noinspection PhpUndefinedVariableInspection */
$cacheService->set($cacheKey, $response->content, $expire);

$dep = $elementsService->stopCollectingCacheTags();
$dep->tags[] = 'element-api';
$cacheService->set($cacheKey, $response->content, $expire, $dep);
}

// Don't double-encode the data
Expand Down

0 comments on commit 4c08623

Please sign in to comment.