REST GET sem armazenamento em cache

11

Usando estedrupal gprr comando do tutorial do Console do Drupal , criei um recurso REST personalizado no Drupal 8. Consigo usar esse recurso para recuperar um objeto JSON simples que diz olá ao usuário atual executando GET on:

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

O JSON retornado fica assim:

{ "hello": "tyler" }

Isso é de se esperar, quando eu estiver logado. Mas quando eu efetuo logout e faço outro GET no recurso, o mesmo resultado é retornado :

{ "hello": "tyler" }

Fazer uma limpeza completa do cache do Drupal corrige esse problema, mas gostaria de desabilitar especificamente o armazenamento em cache neste recurso. Como eu posso fazer isso?

Como solução alternativa, pensei que adicionar um carimbo de data / hora à string de consulta funcionaria:

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

Mas isso também retorna exatamente o mesmo resultado , independentemente do valor do carimbo de data / hora na string de consulta.

Por uma questão de brevidade, aqui está o código do esqueleto para criar o recurso 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()
    ));
  }

}

Existe uma configuração / configuração que preciso definir neste plug-in para desativar o cache em solicitações GET?

tyler.frankenstein
fonte

Respostas:

16

Você deseja ler a documentação do Cacheability . diz arrays de renderização, mas também se aplica a objetos de resposta.

ResourceResponse implementa CacheableResponseInterface, que possui o método addCacheableDependency.

Se for possível, evite desativar o cache (o que você faria definindo a idade máxima do cache como 0), mas adicione os contextos e as tags de cache necessários.

No seu cache, isso significa que tudo o que você precisa fazer é $ response-> addCacheableDependency ($ account).

Você também não precisa de getAccount (), basta usar currentUser () diretamente, é um proxy.

Berdir
fonte
3
Você também deve evitar o uso \Drupalem locais onde pode injetar o serviço, que com base no código comentado, parece que você pode fazer aqui.
mpdonadio
11

Eu tive o mesmo problema.

Depois de ler a documentação e examinar esta página, consegui desligar o cache do meu endpoint personalizado. Aqui está um exemplo do meu código de trabalho dentro da função get () para meu endpoint:

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

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

Adicionando isso para referência futura, espero que ajude quem precisa.

Página de documentação CacheableResponseTrait

redbrickone
fonte
Não funciona !!!!
podarok
@podarok - isso também não funcionou inicialmente para mim; depois de emitir mais um drush cr, funcionou todas as vezes depois.
tyler.frankenstein
1
funcionou como um encanto.
Mohamed Osama Gbril 25/10/19
5

Eu também tive o mesmo problema e a solução para isso é:

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

Você também pode ver a documentação CacheableMetadata e os contextos de cache .

Iheb
fonte