Caching ActiveModel::Serializers on Heroku
If you've been using ActiveModel::Serializer, then you're in for a treat. Rails' caching is now a first class citizen of the library, and enabling it couldn't be easier.
I like to define global serializer settings in an
ApplicationSerializer and then extend it in all my other serializers. That way, everything is automatically cached – and since we're delegating the cache_key to the underlying object, the serializer will use whatever the object determines that to be. It can go in
app/serializers and would look like this:
class ApplicationSerializer < ActiveModel::Serializer cached delegate :cache_key, to: :object end
If your model is ActiveRecord based, the cache key will look like this by default:
Since the updated_at timestamp is in there, it should automatically bust the cache if the object is changed. It gets a little more complicated if you have nested models, though: changing a child record won't bust the cache of the parent unless you touch it whenever you make a change, like so:
belongs_to :parent, touch: true
The Cache Store
In development and test, you can enable Rails' in-memory cache store. It comes with 32MB by default, which should be plenty for local development. Add the following line to your
config/test.rb and you're done:
config.cache_store = :memory_store
That isn't going to cut it for your staging and production servers, though. The easiest thing to do is add
memcached to those environments. If you're running on AWS, you can get a developer MemCachier instance for free. That should be fine until you have serious traffic. On Heroku, it's as simple as this:
heroku addons:add memcachier:dev
Now you'll need to set up your application to actually use memcached. Just as we should expect, this is super easy. Just add this to your Gemfile and bundle ...
gem "dalli" gem "memcachier"
... and add this to your environments/production.rb and staging.rb.
config.cache_store = :dalli_store
That's it! Enjoy a practically free speed boost for your API!