REST GET ohne Caching

11

Mit dem Drupal Console- Befehl dieses Tutorialsdrupal gprr habe ich in Drupal 8 eine benutzerdefinierte REST-Ressource erstellt. Mit dieser Ressource kann ich ein einfaches JSON-Objekt abrufen, das den aktuellen Benutzer begrüßt, indem ich ein GET für Folgendes ausführe:

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

Der zurückgegebene JSON sieht dann folgendermaßen aus:

{ "hello": "tyler" }

Dies ist zu erwarten, da ich angemeldet bin. Wenn ich mich jedoch abmelde und ein weiteres GET für die Ressource durchführe, wird dasselbe Ergebnis zurückgegeben :

{ "hello": "tyler" }

Durch das Löschen eines vollständigen Drupal-Cache wird dieses Problem behoben, aber ich möchte das Caching für diese Ressource speziell deaktivieren. Wie kann ich das machen?

Als Problemumgehung dachte ich, dass das Hinzufügen eines Zeitstempels zur Abfragezeichenfolge funktionieren würde:

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

Dies liefert jedoch auch genau das gleiche Ergebnis , unabhängig davon, welcher Zeitstempelwert in der Abfragezeichenfolge enthalten ist.

Der Kürze halber ist hier der Grundgerüstcode zum Erstellen der GET-Ressource:

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()
    ));
  }

}

Gibt es eine Konfiguration / Einstellung, die ich für dieses Plugin festlegen muss, um das Caching bei GET-Anforderungen zu deaktivieren?

tyler.frankenstein
quelle

Antworten:

16

Sie möchten die Cacheability-Dokumentation lesen . Es heißt Render-Arrays, aber es gilt auch für Antwortobjekte.

ResourceResponse implementiert CacheableResponseInterface mit der Methode addCacheableDependency.

Wenn möglich, möchten Sie vermeiden, den Cache zu deaktivieren (was Sie tun würden, indem Sie das maximale Alter des Caches auf 0 setzen), aber die erforderlichen Cache-Kontexte und Cache-Tags hinzufügen.

In Ihrem Cache bedeutet dies, dass Sie nur $ response-> addCacheableDependency ($ account) tun müssen.

Sie brauchen auch nicht getAccount (), verwenden Sie einfach currentUser () direkt, es ist ein Proxy.

Berdir
quelle
3
Sie sollten es auch vermeiden, \Drupalan Orten zu verwenden, an denen Sie den Dienst einspeisen können. Dies sieht basierend auf Ihrem auskommentierten Code so aus, wie Sie es hier tun können.
mpdonadio
11

Ich hatte das gleiche Problem.

Nachdem ich die Dokumentation gelesen und diese Seite durchgesehen hatte, konnte ich den Cache für meinen benutzerdefinierten Endpunkt schließen. Hier ist ein Beispiel für meinen Arbeitscode in der Funktion get () für meinen Endpunkt:

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

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

Wenn Sie dies zum späteren Nachschlagen hinzufügen, hoffen Sie, dass dies jedem hilft, der es benötigt.

CacheableResponseTrait- Dokumentationsseite

Redbrickone
quelle
Funktioniert nicht !!!!
Podarok
@podarok - das hat zuerst auch bei mir nicht funktioniert, dann hat es nach jeder weiteren Ausgabe drush crjedes Mal danach funktioniert.
tyler.frankenstein
1
Lief wie am Schnürchen.
Mohamed Osama Gbril
5

Ich hatte auch das gleiche Problem und die Lösung dafür ist:

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

Sie können auch die Dokumentationen CacheableMetadata und Cache-Kontexte anzeigen .

Iheb
quelle