如何控制 Drupal 8/9 中通过 JSON:API 渲染的节点的可缓存性?

问题描述 投票:0回答:2

我们有一个无头 Drupal 站点,它使用 JSON:API 公开 API。我们公开的资源之一是一种内容类型,它内部有一个计算/计算字段,可生成限时链接。该链接仅在 120 秒内有效,但 JSON:API 似乎希望将包含字段数据的响应缓存更长的时间。

理想情况下,我们不想完全关闭这些节点的缓存,因为它们确实会非常频繁地被请求。相反,我们只想将缓存限制在 60 秒左右。所以,

\Drupal::service('page_cache_kill_switch')->trigger()
不是一个理想的解决方案。

我已经研究过通过

EventSubscriber
上的
KernelEvents::RESPONSE
来改变响应的缓存能力,但这只会影响顶层的处理。例如,JSON:API 单独缓存响应的所有部分(“规范化”),以实现最大缓存效率,因此即使响应不是从缓存提供的,每个节点的 JSON:API 版本也是如此。

我还尝试使用服务注入来包装 JSON:API 的规范器,以便我可以调整缓存最大期限。看起来我需要在字段规范化级别执行此操作,但 JSON:API 模块通过抛出

LogicException
和错误
JSON:API does not allow adding more normalizers!
来阻止这种情况。

caching drupal-8 json-api
2个回答
3
投票

因此,经过一番努力后,解决方案出人意料地简单——不要在响应级别或 JSON:API 级别操作缓存,而是在实体级别操作它!

这有效:

/**
 * Implements hook_ENTITY_TYPE_load() for nodes.
 */
function my_module_node_load(array $entities) {
  foreach ($entities as $entity) {
    assert($entity instanceof NodeInterface);

    if ($entity->bundle() === 'my_content_type') {
      // Cache "my_content_type" entities for up to 60 seconds.
      $entity->addCacheableDependency(
        (new CacheableMetadata())->setCacheMaxAge(60)
      );
    }
  }
}

作为奖励,这使用了核心的正常缓存机制;因此,即使这些节点显示在我们的管理页面上,也只会缓存最多 60 秒。


0
投票

此外,还可以使用 JSON:API Response Alter 模块。

© www.soinside.com 2019 - 2024. All rights reserved.