HTTPキャッシング

私たちは、HTTP 1.1のための技術の集合としてHTTPキャッシングを参照し、サーバとのより高速な相互作用を行うために、ブラウザベンダーによって実装します。、送信された場合、これらのHTTPキャッシュメカニズムが有効になり、いくつかのヘッダがあります。

キャッシュ制御

アクションには、特別なヘッダーを設定するためのDSLを提供しますCache-Control。最初の引数は次のようにキャッシュ応答指示である:publicか、"must-revalidate"第二引数のようなオプションのセットである一方で、:max_age

# apps/web/controllers/dashboard/index.rb
require 'hanami/action/cache'

module Web::Controllers::Dashboard
  class Index
    include Web::Action
    include Hanami::Action::Cache

    cache_control :public, max_age: 600
      # => Cache-Control: public, max-age: 600

    def call(params)
      # ...
    end
  end
end

 

有効期限

別のHTTPキャッシュの特別なヘッダがありますExpires。それは理解していない古いブラウザでretrocompatibilityのために使用することができますCache-Control

以下のためのお花見のソリューション期限切れには両方のヘッダを送信することにより、すべてのブラウザのサポートを兼ね備えています。

# apps/web/controllers/dashboard/index.rb
require 'hanami/action/cache'

module Web::Controllers::Dashboard
  class Index
    include Web::Action
    include Hanami::Action::Cache
    expires 60, :public, max_age: 300
      # => Expires: Mon, 18 May 2015 09:19:18 GMT
      #    Cache-Control: public, max-age: 300

    def call(params)
      # ...
    end
  end
end

 

条件付きGET

条件付きGETは、リソースが最後の訪問以来変わっていないブラウザを知らせるために、2段階のワークフローです。最初のリクエストの終了時に、応答は、ブラウザがそれが戻ってくる次回を使用する特別なHTTPレスポンスヘッダを含んでいます。ヘッダは、サーバが計算値と一致した場合、リソースはまだキャッシュされ、304ステータスが(変更されていない)が返されます。

 

ETagを

リソースの新鮮さと一致する最初の方法は、識別子(通常MD5トークン)を使用することです。さんはでそれを指定してみましょうfresh etag:

与えられた識別子が一致しない場合、If-None-Match要求ヘッダーを、要求が返されます200ETag、その値を持つレスポンスヘッダ。ヘッダーが一致しない場合、アクションが停止され、304返されます。

# apps/web/controllers/users/show.rb
require 'hanami/action/cache'

module Web::Controllers::Users
  class Show
    include Web::Action
    include Hanami::Action::Cache

    def call(params)
      @user = UserRepository.new.find(params[:id])
      fresh etag: etag

      # ...
    end

    private

    def etag
      "#{ @user.id }-#{ @user.updated_at }"
    end
  end
end

# Case 1 (missing or non-matching If-None-Match)
# GET /users/23
#  => 200, ETag: 84e037c89f8d55442366c4492baddeae

# Case 2 (matching If-None-Match)
# GET /users/23, If-None-Match: 84e037c89f8d55442366c4492baddeae
#  => 304

 

最終更新日

第二の方法は、経由して、タイムスタンプを使用することですfresh last_modified:

与えられたタイムスタンプが一致しない場合If-Modified-Since、リクエストヘッダを、それが返されます200と、設定しLast-Modifiedたタイムスタンプ値を持つレスポンスヘッダを。タイムスタンプが一致しない場合、アクションが停止され、304返されます。

# apps/web/controllers/users/show.rb
require 'hanami/action/cache'

module Web::Controllers::Users
  class Show
    include Web::Action
    include Hanami::Action::Cache

    def call(params)
      @user = UserRepository.new.find(params[:id])
      fresh last_modified: @user.updated_at

      # ...
    end
  end
end

# Case 1 (missing or non-matching Last-Modified)
# GET /users/23
#  => 200, Last-Modified: Mon, 18 May 2015 10:04:30 GMT

# Case 2 (matching Last-Modified)
# GET /users/23, If-Modified-Since: Mon, 18 May 2015 10:04:30 GMT
#  => 304