REST GET sans mise en cache

11

À l'aide de ce tutoriel, la drupal gprrcommande de la console Drupal , j'ai créé une ressource REST personnalisée dans Drupal 8. Je peux utiliser cette ressource pour récupérer un simple objet JSON qui dit bonjour à l'utilisateur actuel en faisant un GET sur:

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

Le JSON retourné ressemble alors à ceci:

{ "hello": "tyler" }

Cela doit être prévu, car je suis connecté. Mais lorsque je me déconnecte et que je fais un autre GET sur la ressource, le même résultat est renvoyé :

{ "hello": "tyler" }

La suppression d'un cache Drupal complet résout ce problème, mais je voudrais spécifiquement désactiver la mise en cache sur cette ressource. Comment puis je faire ça?

Comme solution de contournement, j'ai pensé que l'ajout d'un horodatage à la chaîne de requête fonctionnerait:

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

Mais cela renvoie également exactement le même résultat , quelle que soit la valeur d'horodatage dans la chaîne de requête.

Par souci de concision, voici le code squelette pour la construction de la ressource 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-t-il une configuration / un paramètre que je dois définir sur ce plugin pour désactiver la mise en cache des requêtes GET?

tyler.frankenstein
la source

Réponses:

16

Vous souhaitez lire la documentation de mise en cache . il indique les tableaux de rendu, mais il s'applique également aux objets de réponse.

ResourceResponse implémente CacheableResponseInterface, qui a la méthode addCacheableDependency.

Si possible, vous voulez éviter de désactiver le cache (ce que vous feriez en définissant l'âge maximum du cache sur 0), mais ajoutez les contextes de cache et les balises de cache nécessaires.

Dans votre cache, cela signifie que tout ce que vous devez faire est $ response-> addCacheableDependency ($ account).

Vous n'avez pas non plus besoin de getAccount (), utilisez simplement currentUser () directement, c'est un proxy.

Berdir
la source
3
Vous devez également éviter d'utiliser \Drupaldans des endroits où vous pouvez injecter le service, ce qui, en fonction de votre code commenté, ressemble à ce que vous pouvez faire ici.
mpdonadio
11

J'ai eu le même problème.

Après avoir lu la documentation et parcouru cette page, j'ai pu fermer le cache de mon point de terminaison personnalisé. Voici un exemple de mon code de travail à l'intérieur de la fonction get () pour mon point de terminaison:

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

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

En ajoutant ceci pour référence future, j'espère que cela aidera toute personne qui en a besoin.

Page de documentation de CacheableResponseTrait

redbrickone
la source
Ne fonctionne pas !!!!
podarok
@podarok - cela n'a pas fonctionné au début pour moi non plus, puis après en avoir émis un de plus, drush crcela a fonctionné à chaque fois par la suite.
tyler.frankenstein
1
travaillé comme un charme.
Mohamed Osama Gbril
5

J'ai également eu le même problème et la solution est:

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

Vous pouvez également voir les documentations CacheableMetadata et les contextes de cache .

Iheb
la source