【问题标题】:How to expire conditional GET cache when locale changes?区域设置更改时如何使条件 GET 缓存过期?
【发布时间】:2016-05-04 19:06:07
【问题描述】:

对于 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 成为 :nl:en 就足够了。

我想在 etag 和 if-modified 中使用它。这样当请求不同的语言时,fresh_when 不会返回缓存的响应。像这样:

  • get /balances/mine, {}, { "Accept-Language" =&gt; "en" } #=> 响应 200 OK
  • get /balances/mine, {}, { "Accept-Language" =&gt; "en", "If-None-Match" =&gt; previous_response.headers["ETag"] } #=> 响应 304 未修改
  • get /balances/mine, {}, { "Accept-Language" =&gt; "nl", "If-None-Match" =&gt; previous_response.headers["ETag"] } #=> 响应 200 OK
  • get /balances/mine, {}, { "Accept-Language" =&gt; "nl", "If-None-Match" =&gt; previous_response.headers["ETag"] } #=> 响应 304 未修改

因此,只有当语言环境与缓存的版本匹配时,响应才会被缓存并返回为 304。

使用 cache() 块,在 Rails 中使用片段缓存,adding a locale is simple。 如何使用fresh_when 方法实现相同的效果?

【问题讨论】:

    标签: ruby-on-rails caching etag


    【解决方案1】:

    解决方案很简单。但仅适用于 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

    使用If-Modified-Since 方法,不可能使缓存过期。由于 Rails 在使用 Conditional GET 时不存储任何缓存,而只会将传入的时间戳与对象上的时间戳进行比较。

    它们都没有能力携带比“只是一个日期”更多的信息。我们需要 rails 来存储它的缓存(就像片段缓存一样),以便同时存储它创建的语言。此方法不允许我们根据语言标头使缓存过期。

    通过仅传递 etag 选项,忽略 if-modified-since 标头:fresh_when(etag: current_user.balance)

    如果没有匹配

    这代表一个实体标签,是所服务内容的标识符。通常这是使用返回对象的 object-id 构建的。

    Conditional Get 允许额外的 etag-builders,命名为 etaggers to be defined

    这可用于将额外信息添加到实体标签中。

    【讨论】:

      猜你喜欢
      • 2012-05-27
      • 1970-01-01
      • 2023-02-10
      • 1970-01-01
      • 2012-07-16
      • 1970-01-01
      • 2015-03-11
      • 2023-04-02
      • 2013-11-20
      相关资源
      最近更新 更多