如何在语言环境发生变化时使条件GET缓存失效?

时间:2016-05-04 09:58:33

标签: ruby-on-rails caching etag

对于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()方法实现相同的目标?

1 个答案:

答案 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-由于

使用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中。