Response Cache

The :response_cache plugin allows for caching and reusing the same HTTP response, while making transparent use of HTTP conditional requests and caching strategies for response cache invalidation, towards improving performance and bandwidth usage (at the expense of writing to and reading from storage).

When the plugin is enabled, cacheable responses will be reused and not trigger a network call for as long as they’re fresh (this is controlled by the peer server via HTTP "cache-control" or "expires" header directives); after that period, responses which advertise some etag or last-modified header will use that information in the next same request (controlled by the URI, HTTP verb, and “vary” HTTP header rules, when available), using the HTTP if-none-match and if-modified-since headers; a 304 status code response will allow reusing the cached response, whereas everything else will invalidate it.

client = HTTPX.plugin(:response_cache)
r1 = client.get("https://nghttp2.org/httpbin/cache")
r1.headers #=> {
#  "content-type"=>"application/json",
#  "content-length"=>"226",
#  "last-modified"=>"Sat, 10 Jun 2023 16:14:35 GMT",
#  "etag"=>"33891c807e4448c780f6fa192d486774", ....
r2 = client.get("https://nghttp2.org/httpbin/cache") #=> no network call, returns r1
r2.status #=> 200
# ... after freshness period

r3 = client.get("https://nghttp2.org/httpbin/cache") #=> conditional request

r3.status #=> 304
r1.body == r2.body #=> true
r1.body == r3.body #=> true

# to wipe out the response cache
client.clear_response_cache

:response_cache_store

The :response_cache_store option can be used to choose a suitable cache store to your needs. The :response_cache plugin ships with two store implementations, :store (the default) and :file_store.

:store

The default :store cache store stores cached responses in memory. It is thread-safe, and can only share cached responses in the scope of the same process.

:file_store

The default :file_store cache store stores cached responses in the file system (in the tempfile directory from your OS by default). It can share cached responses across several process of the same machine.

HTTPX.plugin(:response_cache, response_cache_store: :file_store)

Cache Store Interface compatible Store

You can pass any custom object of yours to this option which implements the Cache Store Interface:

  • get(request) -> returns an instance of HTTPX::Response or nil.
  • set(request, response) -> should cache the response.
  • clear -> deletes all cached responses from the store.

What this plugin is not

This plugin is not an on-demand client-driven cache, where the client can set for how long a given response can be stored. You may want to build your own plugin for that.

Next: Circuit Breaker