语言环境更改时如何使条件 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 缓存响应。像这样:

因此,仅当语言环境与缓存版本匹配时,才会缓存响应并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 添加额外信息。