#0017 HTTP ETag in Rails
This log covers HTTP ETags usage in Rails development. ETag is a key to determine content has changed.
The ETag or entity tag is part of HTTP, the protocol for the World Wide Web. It is one of several mechanisms that HTTP provides for web cache validation, which allows a client to make conditional requests. This allows caches to be more efficient, and saves bandwidth, as a web server does not need to send a full response if the content has not changed.1
Typical Usage
Server returns the response with ETag
value in HTTP response header. The client cache the response content. When client make a request next time which send its saved ETag
with the request in If-None-Match
field. If the ETag
match, the server send back a short response with HTTP 304 Not Modified
status.
Before using refresh_when
- First Request
- Render body
- Create ETag (
headers['Etag'] = Digest::MD5.hexdigest(body)
) - Include response body and ETag in the response
- Client cache response
- Second Request
- Render body
- Create ETag (automatically created using response body)
- Compare ETag
- Not include body in response if ETag match
- Client render response from cache
The entire body is required to process in order to generate the ETag which is not efficient.
After using refresh_when
class ItemsController < ApplicationController
def show
@item = Item.find(params[:id])
fresh_when(@item)
end
end
When there are multiple arguments (ETag computation do support multiple values),
class ItemsController < ApplicationController
# Equivalent to `fresh_when([@item, current_user.id])` inside `show`
etag { current_user.id }
def show
@item = Item.find(params[:id])
fresh_when(@item)
end
end
Using refresh_when
make the ETag generating process much efficient.
- First Request
- Render body
- Create ETag (
headers['Etag'] = Digest::MD5.hexdigest(@item.cache_key)
) - Include response body and ETag in the response
- Client cache response
- Second Request
- Render body
- Create ETag (automatically created using
cache_key
) - Compare ETag
- Not include body in response if ETag match
- Client render response from cache
-
https://en.wikipedia.org/wiki/HTTP_ETag ↩