2016-05-04 58 views
1

對於JSON API,我使用fresh_when,像這樣(簡化):如何在語言環境更改時過期使用條件GET緩存?

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

這適用的ETag(如果 - 無 - 匹配)和的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之後使用它。這樣fresh_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

該解決方案很簡單。但僅適用於該ETag的-方法:

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 

如果-Modified-Since的

隨着If-Modified-Since方法,它是不可能過期緩存。由於Rails在使用Conditional GET時不存儲任何緩存,但僅比較時間戳和對象上的時間戳。

這些都沒有能力攜帶更多的信息比「只是一個日期」。我們需要rails來存儲它的緩存(比如片段緩存),以便還存儲它創建的語言。這種方法不允許我們根據語言頭來使緩存過期。

是,只透過etag選項,如果改性-因爲頭被忽略:fresh_when(etag: current_user.balance)

如果-無 - 匹配

這代表一個實體標籤,並且對於內容作爲一個識別符提供服務。通常這是使用返回對象的object-id構建的。

條件獲取允許額外的etag-builders,名爲etaggersto be defined

這可用於向實體標籤添加額外信息。

相關問題