语言环境更改时如何使条件 GET 缓存过期?
How to expire conditional GET cache when locale changes?
对于 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
是一个更复杂的库,但对于这个例子来说,足以说明 header "Accept-Language: nl"
或 "Accept-Language: en"
将导致 @locale
是 :nl
或 :en
.
我想在 etag 中使用它,if-modified 因为。这样 fresh_when 在请求不同语言时不会 return 缓存响应。像这样:
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未修改
因此,仅当语言环境与缓存版本匹配时,才会缓存响应并return编辑为 304。
使用 cache()
个块,在 Rails、adding a locale is simple 中使用片段缓存。
如何使用 fresh_when
方法实现同样的效果?
解决方法很简单。但仅适用于 etags-method:
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
时不存储任何缓存,而只是将传入的时间戳与 object 上的时间戳进行比较。
它们都没有能力携带比 "Just a Date" 更多的信息。我们需要 rails 来存储它的缓存(就像片段缓存一样),以便也存储它的创建语言。此方法不允许我们使基于语言 header.
的缓存过期
通过仅传递 etag
选项,if-modified-since header 将被忽略:fresh_when(etag: current_user.balance)
If-None-Match
这代表一个 entity-tag,是所提供内容的标识符。通常这是使用返回的 object 的 object-id 构建的。
条件获取允许额外的 etag-builders,命名为 etaggers
to be defined。
这可用于向 entity-tag 添加额外信息。
对于 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
是一个更复杂的库,但对于这个例子来说,足以说明 header "Accept-Language: nl"
或 "Accept-Language: en"
将导致 @locale
是 :nl
或 :en
.
我想在 etag 中使用它,if-modified 因为。这样 fresh_when 在请求不同语言时不会 return 缓存响应。像这样:
get /balances/mine, {}, { "Accept-Language" => "en" }
#=> 响应 200 OKget /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 OKget /balances/mine, {}, { "Accept-Language" => "nl", "If-None-Match" => previous_response.headers["ETag"] }
#=> 响应304未修改
因此,仅当语言环境与缓存版本匹配时,才会缓存响应并return编辑为 304。
使用 cache()
个块,在 Rails、adding a locale is simple 中使用片段缓存。
如何使用 fresh_when
方法实现同样的效果?
解决方法很简单。但仅适用于 etags-method:
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
时不存储任何缓存,而只是将传入的时间戳与 object 上的时间戳进行比较。
它们都没有能力携带比 "Just a Date" 更多的信息。我们需要 rails 来存储它的缓存(就像片段缓存一样),以便也存储它的创建语言。此方法不允许我们使基于语言 header.
的缓存过期通过仅传递 etag
选项,if-modified-since header 将被忽略:fresh_when(etag: current_user.balance)
If-None-Match
这代表一个 entity-tag,是所提供内容的标识符。通常这是使用返回的 object 的 object-id 构建的。
条件获取允许额外的 etag-builders,命名为 etaggers
to be defined。
这可用于向 entity-tag 添加额外信息。