'Rails: Cache API request with Typhoeus

How can I cache api requests with Typhoeus gem in Rails? I gave up trying to do it by myself after 2 horus trying.

I have the following code:

            hydra = Typhoeus::Hydra.new
            requests = urls.map do |url|
                request = Typhoeus::Request.new(url, followlocation: true)
                hydra.queue(request)
                request
            end
            hydra.run

Their docs say this "Typhoeus includes built in support for caching. In the following example, if there is a cache hit, the cached object is passed to the on_complete handler of the request object."

class Cache
  def initialize
    @memory = {}
  end

  def get(request)
    @memory[request]
  end

  def set(request, response)
    @memory[request] = response
  end
end

Typhoeus::Config.cache = Cache.new

Typhoeus.get("www.example.com").cached?
#=> false
Typhoeus.get("www.example.com").cached?
#=> true

But I didn't understand where to put this code.



Solution 1:[1]

Create an initializer to setup the cache. Something like: (config/initializers/typhoeus.rb)

redis = Redis.new(url: "your redis url")
Typhoeus::Config.cache = Typhoeus::Cache::Redis.new(redis, default_ttl: 60)

Then in your request you can add caching related options.

request = Typhoeus::Request.new(url,
                                method: method,
                                params: params,
                                body: body,
                                headers: request_headers,
                                cache_ttl: 10, 
                                cache_key: "unique_key")

request.run

The ttl is in seconds. The Typhoeus cache_key by default is:

Digest::SHA1.hexdigest "#{self.class.name}#{base_url}#{hashable_string_for(options)}"

They don't document that. You have to look at the source to figure it out.
It's probably fine, but I demonstrate how to set your own if you want above.

If you want to make a request without using the cache pass cache: false in the options as the cache will be on by default now for all requests.

Solution 2:[2]

Just to echo what https://stackoverflow.com/users/215708/jacklin said,

The easiest option that worked for me was:

  1. As mentioned before configure rails cache with desired cache middleware
  2. Point Typhoeus in config file config/initializers/typhoeus.rb to use rails cache as shown below
require 'typhoeus/cache/rails'
Typhoeus::Config.cache = Typhoeus::Cache::Rails.new
  1. Thats it.Typhoeus::Request.new calls would automatically be cached.

Side Note if Using Redis The response.body object is of type string which I discovered after playing with the Rails cache. Since you want to cache the response and keep referencing the cache, JSON.parse(response.body) should give you a hash instead. I believe its a redis thing.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2