2016-05-04 8 views
1

Für eine JSON-API, ich fresh_when verwende, wie so (vereinfacht):Wie konditionalen GET-Cache ablaufen, wenn Gebietsschema ändert?

class BalancesController < ApplicationController 
    def mine 
    fresh_when(current_user.balance) 
    end 
end 

Dies funktioniert mit ETags (If-None-Match) und updated_at (If-Modified-Since) gut.

Allerdings möchte ich den Cache für verschiedene Sprachen ungültig machen. Vereinfacht:

class BalancesController < ApplicationController 
    before_action :set_locale 
    def mine 
    fresh_when(current_user.balance) 
    end 

    private 
    def set_locale 
    @locale = locale_from_headers 
    end 
end 

locale_from_headers ist ein komplexeres lib, aber für dieses Beispiel ist es genug, um zu sagen, dass ein Kopf "Accept-Language: nl" oder "Accept-Language: en" in @locale führt entweder :nl oder :en.

Ich möchte dies im Etag und wenn-modifiziert seitdem verwenden. So dass das Fresh_when eine zwischengespeicherte Antwort nicht zurückgibt, wenn eine andere Sprache anfordert. Wie so:

  • get /balances/mine, {}, { "Accept-Language" => "en" } # => Antwort 200 OK
  • get /balances/mine, {}, { "Accept-Language" => "en", "If-None-Match" => previous_response.headers["ETag"] } # => Antwort 304 nicht
  • modifizierte
  • get /balances/mine, {}, { "Accept-Language" => "nl", "If-None-Match" => previous_response.headers["ETag"] } # => Antwort 200 OK
  • get /balances/mine, {}, { "Accept-Language" => "nl", "If-None-Match" => previous_response.headers["ETag"] } # => Antwort 304 nicht
  • modifizierte

So werden Antworten zwischengespeichert und nur als 304 zurückgegeben, wenn die Ländereinstellungen mit der zwischengespeicherten Version übereinstimmen.

Mit cache() Blöcke, mit Fragment-Caching in Rails, adding a locale is simple. Wie erreiche ich das Gleiche mit den fresh_when Methoden?

Antwort

0

Die Lösung war einfach. Aber funktioniert nur mit der etags-Methode:

class BalancesController < ApplicationController 
    etag { current_locale } 

    def mine 
    fresh_when(etag: current_user.balance) 
    end 

    private 
    def current_locale 
    @locale ||= locale_from_headers 
    end 
end 

If-Modified-Since

Mit dem If-Modified-Since Verfahren ist es nicht möglich, den Cache abläuft. Da Rails bei Verwendung der Conditional GET keinen Cache speichert, sondern nur Zeitstempel mit Zeitstempeln für die Objekte vergleicht.

Keine von diesen hat die Fähigkeit, mehr Informationen als "nur ein Datum" zu tragen. Wir würden Rails benötigen, um seine Caches zu speichern (wie beim Fragment-Caching), um auch die Sprache zu speichern, für die sie erstellt wurde. Mit dieser Methode können wir einen Cache nicht basierend auf dem Sprachenheader ablaufen lassen.

nur die etag Option Durch die Übergabe, die if-modified-since Header werden ignoriert: fresh_when(etag: current_user.balance)

If-None-Match

Dies entspricht einem Entity-Tag, und ist eine Kennung für den Inhalt ist serviert. In der Regel wird dies mithilfe der Objekt-ID des zurückgegebenen Objekts erstellt.

Bedingte Get ermöglicht zusätzliche Etag-Builder, genannt etaggersto be defined.

Dies kann verwendet werden, um dem Entitäts-Tag zusätzliche Informationen hinzuzufügen.