2016-05-04 8 views
1

Для API JSON, я использую fresh_when, например, так (упрощенно):Как исправить условный кеш GET при изменении локали?

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

Это работает с ETags (If-None-Match) и updated_at (If-Modified-Since) просто отлично.

Однако я хочу аннулировать кеш для разных языков. Упрощенная:

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 является более сложным Lib, но для этого примера достаточно, чтобы сказать, что заголовок "Accept-Language: nl" или "Accept-Language: en" приведет к @locale быть либо :nl или :en.

Я хочу использовать это в etag и if-modified since. Чтобы new_when не возвращал кешированный ответ при запросе другого языка. Как так:

  • get /balances/mine, {}, { "Accept-Language" => "en" } # => ответ 200 OK
  • get /balances/mine, {}, { "Accept-Language" => "en", "If-None-Match" => previous_response.headers["ETag"] } # => ответ 304 не модифицирована
  • get /balances/mine, {}, { "Accept-Language" => "nl", "If-None-Match" => previous_response.headers["ETag"] } # => ответ 200 OK
  • get /balances/mine, {}, { "Accept-Language" => "nl", "If-None-Match" => previous_response.headers["ETag"] } # => ответ 304 не модифицирована

Итак, ответы кэшируются и возвращаются как 304 только тогда, когда локали соответствуют кешированной версии.

С блоками cache() с использованием кеширования фрагментов в Rails, adding a locale is simple. Как добиться этого с помощью методов fresh_when?

ответ

0

Решение было простым. Но работает только с ETags-метода:

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

С помощью метода If-Modified-Since, не представляется возможным истекает кэш. Так как Rails не хранит кеш при использовании Conditional GET, а сравнивает только те, которые были отмечены в метках времени с отметками времени на объектах.

Ни один из них не имеет возможности иметь больше информации, чем «Только дата». Нам понадобятся рельсы для хранения своих кешей (например, с кешированием фрагментов), чтобы также сохранить язык, на котором он был создан. Этот метод не позволит нам истечь кеш, основанный на заголовке языка.

Передавая только etag опцию, если-Modified-Since заголовки игнорируются: fresh_when(etag: current_user.balance)

If-None-Match

Это представляет сущность-тег, и идентификатор для содержания являющегося служил. Обычно это создается с использованием идентификатора объекта возвращаемого объекта.

Условный Get позволяет использовать дополнительные этажи, названные etaggersto be defined.

Это может использоваться для добавления дополнительной информации в тег сущности.