PhoenixETag
Hex: https://hex.pm/packages/phoenix_etag
GitHub: https://github.com/michalmuskala/phoenix_etag
Conditional request (ETag & modified-since) support for Phoenix.
Usage
The library provides a replacement function for Phoenix.Controller.render/1-4
called PhoenixETag.render_if_stale/1-4
accepting exactly the same arguments.
When called the function expects the view to implement an additional callback:
stale_checks/2
similar to render/2
that is responsible for returning the
etag value and/or last modified value for the current resource.
Additional helpers PhoenixETag.schema_etag/1
and PhoenixETag.schema_last_modified/1
are provided for easily generating the values from a single or multiple schema structs.
# controller
import PhoenixETag
def show(conn, %{"id" => id}) do
data = MyApp.load_data(id)
render_if_stale(conn, :show, data: data)
end
# view
import PhoenixETag
def stale_checks("show." <> _format, %{data: data}) do
[etag: schema_etag(data), last_modified: schema_last_modified(data)]
end
Both the etag and last_modified values are optional. The first one will add an
etag
header to the response and perform a stale check against the
if-none-match
header. The second one will add a last-modified
header to the
response and perform a stale check against the if-modified-since
header.
If the headers indicate cache is fresh a 304 Not Modified
response is triggered,
and rendering of the response is aborted. If headers indicate cache is stale,
render proceeds as normal, except the extra headers are added to the response.
This allows both saving rendering time on the server and skipping downloading data, which can be significant optimisations for large responses.
The library took some ideas from hex_web and borrowed http dates parsing and formatting from cowlib v2.0.