Drupal 8自定义endpoint接口文章列表缓存不自动更新如何解决
Drupal 缓存体系核心概念及自定义endpoint缓存失效解决方案
核心缓存概念解释
- cache keys:缓存的唯一标识符,Drupal通过这组键值定位对应的缓存条目,同一个endpoint如果返回不同内容(比如分页、不同筛选条件)需要生成不同的cache keys。
- cache tags:缓存依赖标签,用来标记缓存内容关联的数据源,只要对应数据源发生更新,Drupal会自动失效所有带对应标签的缓存。比如所有article节点的公共标签是
node_list:article,单个节点的标签是node:[nid]。 - cache contexts:缓存上下文,用来标记缓存内容受哪些环境变量影响,比如当前用户权限、语言、请求参数等,同一个请求如果上下文不同会生成不同的缓存版本。比如列表如果对匿名和登录用户返回不同内容,就需要加
user.permissions上下文。
问题根源
当前endpoint返回内容后没有正确附加缓存元数据,Drupal缓存后无法感知关联的article节点更新,因此只能手动清缓存才能看到最新内容。
具体实现方案
如果是自定义控制器返回JSON格式的article列表,可参考如下代码实现:
<?php namespace Drupal\your_module\Controller; use Drupal\Core\Cache\CacheableJsonResponse; use Drupal\node\Entity\Node; class ArticleListController extends ControllerBase { public function getArticleList() { // 查询已发布的article类型节点 $query = \Drupal::entityTypeManager()->getStorage('node')->getQuery() ->condition('type', 'article') ->condition('status', 1) ->accessCheck(TRUE) ->sort('created', 'DESC'); $nids = $query->execute(); $nodes = Node::loadMultiple($nids); $articles = []; foreach ($nodes as $node) { $articles[] = [ 'id' => $node->id(), 'title' => $node->getTitle(), 'created_time' => $node->getCreatedTime(), 'body' => $node->body->value, ]; } // 构建带缓存元数据的响应 $response = new CacheableJsonResponse($articles); // 附加缓存标签:关联所有article节点列表,新增/修改/删除article时自动失效该缓存 $response->getCacheableMetadata()->addCacheTags(['node_list:article']); // 附加缓存上下文:按实际业务需求添加,示例为受用户权限、内容语言影响的场景 $response->getCacheableMetadata()->addCacheContexts(['user.permissions', 'languages:language_content']); // 如有分页、筛选等参数,添加对应cache keys // $response->getCacheableMetadata()->setCacheKeys(['your_module_article_list', $page]); return $response; } }
如果你是基于Views生成的REST export endpoint,不需要自定义代码,直接进入对应Views的高级设置页,将缓存策略设置为「基于标签的缓存」即可,Views会自动附加
node_list:article标签实现自动失效。
验证逻辑
完成配置后,新增/修改/删除任意article节点时,Drupal核心会自动触发node_list:article标签的缓存失效动作,无需手动清理缓存,下次请求endpoint就会返回最新数据。
内容的提问来源于stack exchange,提问作者user3373326
相关产品推荐
相关产品推荐

