简体   繁体   中英

How can I cache external API requests to the SQL database using Rails cache API?

I'm just wondering how I can cache slow requests to external APIs in the database, as I do not want to maintain a memcache service, but I do want a distributed system that will work across multiple dynos and workers on heroku.

I can do it by building my own cache table, but I'm wondering if there's an easier way, especially one that works with the existing caching syntax.

Thanks!

You can cache just about anything in Rails via a call to Rails.cache.fetch . You pass in a key for the cache to look up, and if there's a value in the cache (a "cache hit") then it will get used instead of your slow code.

Let's say we've got an API that takes two airport codes and a date, and returns the best price it can find. This can be a slow lookup, so it's a good candidate for caching:

def find_best_price(start_airport, end_airport, date)
  Rails.cache.fetch(cache_key_for(start_airport, end_airport, date)) do
    AirportPriceAPI.find_best_price(start_airport, end_airport, date)
  end
end

# Different routes & dates will have different prices, so we 
# need to have different cache keys for them.
def cache_key_for(start_airport, end_airport, date)
  "best_price:#{start_airport}:#{end_airport}:#{date}"
end

You can configure the data store for your cache in config/application.rb by setting config.cache_store . Rails has several kinds built in, but not all are suitable for Heroku. You can't use the FileStore because dynos don't have persistent storage and it's not shared between dynos. MemoryStore isn't shared across dynos and will be wiped out if your dyno restarts.

Your best bet for Heroku is the MemCacheStore . It's supported out-of-the-box in Rails, and Heroku will give you 30Mb of memcache space for free . It's fast and perfect for use between multiple dynos.

But, if you did want to cache values in a database, you can provide your app with a custom cache class . All you have to do is extend ActiveSupport::Cache::Store and be sure to implement read , write , exist? , delete , and fetch . And someone's already packaged a DB-backed cache store as a gem , so you don't even have to implement the low-level details yourself. :)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM