HTTParty cache

Implements HTTP caching support to HTTParty requests by following servers' headers such as Cache-Control, specifically the max-age, must-revalidate andno-cache directives, Vary, ETag, Last-Modified to perform response validation.

Use

Add this gem to your Gemfile and install dependencies.

Configure your HTTParty client to use a cache store and perform caching:

require 'httparty'
require 'httparty/cache'

class Client
  include HTTParty
  include HTTParty::Cache

  caching true
  cache_store :memory
end

Caching requisites

  • GET requests only.

  • The server must send a Cache-Control header. Otherwise this gem will always revalidate.

  • A request is revalidated when:

    • The server sends a no-store directive.
    • The server sends a no-cache directive.
    • The server sends a max-age=0,must-revalidate directive.
  • A request is stale when its age is greater than max-age.

Cache stores

Requests are stored by their URL and a cache key, and point at the latest response.

The cache key is generated from requested URL and headers used. If the headers change for every request or are sensitive (X-* headers used for bespoke authentication), you can add the cache_key: 'string' option to the request.

url = 'https://example.org'
sensitive_token = 'token'

HTTParty.get(
  url,
  headers: { 'X-Token': sensitive_token },
  cache_key: url
)

Otherwise you'll see many requests cached all pointing to the same response.

Date, Authorization, Signature and Cookie headers are already ignored.

Responses are stored by their URL and a cache key composed by its Vary headers. This way if you send a request header that could change the response, you'll get a new one.

Redis

If you want to use Redis as a cache store:

  1. Add redis-client and optionally hiredis-client gems to your Gemfile.

  2. Set the environment variable REDIS_URL with the server URL, or initialize the cache store with a custom URL.

   require 'httparty'
   require 'httparty/cache'
   require 'httparty/cache/store/redis'

   class Client
     include HTTParty
     include HTTParty::Cache

     caching true
     cache_store :redis
     # or
     cache_store HTTParty::Cache::Store::Redis.new(redis_url: 'redis://redis.provider:6379')
   end

Jekyll

If you want to use Jekyll as a cache store, for instance while writing a plugin using HTTParty:

require 'httparty'
require 'httparty/cache'
require 'httparty/cache/store/jekyll'

class Client
    include HTTParty
    include HTTParty::Cache

    caching true
    cache_store :jekyll
    # or
    cache_store HTTParty::Cache::Store::Jekyll.new(name: 'My::Jekyll::Cache')
end

Caveats!

  • Response marshaling has been changed to prevent stack level too deep exceptions while marshaling the request. Bringing a response from the cache will have a request with the original HTTP method, path and headers sent.