REST GET без кеширования

11

Используя эту учебнуюdrupal gprr команду Drupal Console , я создал собственный ресурс REST в Drupal 8. Я могу использовать этот ресурс для извлечения простого объекта JSON, который говорит привет текущему пользователю, выполнив GET для:

http://localhost/example/hello?_format=json

Возвращенный JSON выглядит следующим образом:

{ "hello": "tyler" }

Этого и следовало ожидать, так как я вошел в систему. Но когда я выхожу из системы и делаю еще один GET для ресурса, возвращается тот же результат :

{ "hello": "tyler" }

Полная очистка кэша Drupal устраняет эту проблему, но я бы хотел специально отключить кэширование на этом ресурсе. Как я могу это сделать?

В качестве обходного пути я подумал, что добавление метки времени в строку запроса будет работать:

http://localhost/example/hello?_format=json&time=123456789

Но это также возвращает тот же самый результат , независимо от того, какое значение метки времени находится в строке запроса.

Для краткости, вот скелетный код для создания ресурса GET:

class ExampleHello extends ResourceBase {

  /**
   * {@inheritdoc}
   */
  public static function create(/* ... */) {
    return new static(/* ... */);
  }

  /**
   * Constructs a Drupal\rest\Plugin\ResourceBase object.
   */
  public function __construct(/* ... */) {
    parent::__construct(/* ... */);
    // ...
  }

  /*
   * Responds to GET requests.
   */
  public function get() {

    $account = \Drupal::currentUser()->getAccount();
    if (!$account->id()) {
      return new ResourceResponse(array(
        'welcome' => 'visitor'
      ));
    }
    return new ResourceResponse(array(
      'hello' => $account->getAccountName()
    ));
  }

}

Есть ли какая-либо конфигурация / настройка, которую мне нужно установить для этого плагина, чтобы отключить кэширование на GET-запросах?

tyler.frankenstein
источник

Ответы:

16

Вы хотите прочитать документацию Cacheability . он говорит рендеринг массивов, но это также относится к объектам ответа.

ResourceResponse реализует CacheableResponseInterface, который имеет метод addCacheableDependency.

Если это возможно, вы хотите избежать отключения кэша (что можно было бы сделать, установив максимальный возраст кэша на 0), но добавьте необходимые контексты кэша и теги кэша.

В вашем кеше это означает, что все, что вам нужно, это $ response-> addCacheableDependency ($ account).

Вам также не нужен getAccount (), просто используйте currentUser () напрямую, это прокси.

Berdir
источник
3
Вам также следует избегать использования \Drupalв местах, где вы можете внедрить сервис, который на основе вашего закомментированного кода выглядит так, как вы можете сделать здесь.
mpdonadio
11

Я была такая же проблема.

Прочитав документацию и просмотрев эту страницу, я смог отключить кэш для своей пользовательской конечной точки. Вот пример моего рабочего кода внутри функции get () для моей конечной точки:

$build = array(
  '#cache' => array(
    'max-age' => 0,
  ),
);

return (new ResourceResponse($myResponse))->addCacheableDependency($build);

Добавляя это для дальнейшего использования, надеюсь, это поможет всем, кому это нужно.

Страница документации CacheableResponseTrait

redbrickone
источник
Не работает !!!!
подарок
@podarok - сначала у меня это тоже не получалось, потом после выпуска еще одного drush crработало каждый раз потом.
tyler.frankenstein
1
работал как шарм.
Мохамед Усама Гбрил
5

У меня также была та же проблема, и решение для этого:

$response->getCacheableMetadata()->addCacheContexts(['url.query_args', 'url.path']);

Вы также можете увидеть документацию CacheableMetadata и контекстов кэша .

Iheb
источник