对于JSON API,我使用fresh_when
,就像这样(简化):
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
是一个更复杂的库,但对于此示例,只需说标题"Accept-Language: nl"
或"Accept-Language: en"
将导致@locale
为{{1} }或:nl
。
我想在etag和if-modified中使用它。因此,当请求不同的语言时,fresh_when不会返回缓存的响应。像这样:
:en
#=&gt;回复200 OK get /balances/mine, {}, { "Accept-Language" => "en" }
#=&gt;响应304未修改get /balances/mine, {}, { "Accept-Language" => "en", "If-None-Match" => previous_response.headers["ETag"] }
#=&gt;回复200 OK get /balances/mine, {}, { "Accept-Language" => "nl", "If-None-Match" => previous_response.headers["ETag"] }
#=&gt;响应304未修改因此,只有当语言环境与缓存版本匹配时,响应才会被缓存并返回为304。
使用get /balances/mine, {}, { "Accept-Language" => "nl", "If-None-Match" => previous_response.headers["ETag"] }
块,在Rails中使用片段缓存adding a locale is simple。
如何使用cache()
方法实现相同的目标?
答案 0 :(得分: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
方法,无法使缓存失效。由于Rails在使用Conditional GET
时不存储任何缓存,而只是在时间戳中传递与对象上的时间戳相比较。
这些人都没有能力携带比“Just a Date”更多的信息。我们需要rails来存储它的缓存(比如片段缓存),以便存储它为其创建的语言。此方法不允许我们根据语言标头使缓存失效。
仅传递etag
选项,将忽略if-modified-since标头:fresh_when(etag: current_user.balance)
这表示实体标记,并且是正在提供的内容的标识符。通常,这是使用要返回的对象的object-id构建的。
Conditional Get允许额外的etag-builders,名为etaggers
to be defined。
这可用于将额外信息添加到entity-tag中。