Best way to cache a response in Sinatra?

2019-03-09 09:56发布

I'm building a simple app on the side using an API I made with Sinatra that returns some JSON. It's quite a bit of JSON, my app's API relies on a few hundred requests to other APIs.

I can probably cache the results for 5 days or so, no problem with the data at all. I'm just not 100% sure how to implement the caching. How would I go about doing that with Sinatra?

2条回答
老娘就宠你
2楼-- · 2019-03-09 10:14
get '/my_data/:id' do
  # security check for file-based caching
  raise "invalid id" if params[:id] =~ /[^a-z0-9]/i
  cache_file = File.join("cache",params[:id])
  if !File.exist?(cache_file) || (File.mtime(cache_file) < (Time.now - 3600*24*5))
    data = do_my_few_hundred_internal_requests(params[:id])
    File.open(cache_file,"w"){ |f| f << data }
  end
  send_file cache_file, :type => 'application/json'
end

Don't forget to mkdir cache.

alternatively you could use memcache-client, but it will require you to install memcached system-wide.

查看更多
放荡不羁爱自由
3楼-- · 2019-03-09 10:21

Personally, I prefer to use redis for this type of things over memcached. I have an app that I use redis in pretty extensively, using it in a similar way to what you described. If I make a call that is not cached, page load time is upwards of 5 seconds, with redis, the load time drops to around 0.3 seconds. You can set an expires time as well, which can be changed quite easily. I would do something like this to retrieve the data from the cache.

require 'redis'
get '/my_data/:id' do
  redis = Redis.new
  if redis[params[:id]]
    send_file redis[params[:id]], :type => 'application/json'
  end
end

Then when you wanted to save the data to the cache, perhaps something like this:

require 'redis'
redis = Redis.new
<make API calls here and build your JSON>
redis[id] = json
redis.expire(id, 3600*24*5)
查看更多
登录 后发表回答