'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:
- As mentioned before configure
rails cachewith desired cache middleware - Point Typhoeus in config file
config/initializers/typhoeus.rbto use rails cache as shown below
require 'typhoeus/cache/rails'
Typhoeus::Config.cache = Typhoeus::Cache::Rails.new
- Thats it.
Typhoeus::Request.newcalls 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 |
