Bleacher Report is transitioning from a monolithic Rails app towards a service-oriented architecture. In our journey, we’ve established a few guidelines for services. One of those key guidelines is integration with Fastly.
Fastly is a Content Delivery Network (CDN). Their killer feature is caching dynamic content. Fastly uses a system of surrogate keys to accomplish this.
Surrogate keys allow you to selectively purge single or related content. For example, you can purge the surrogate key
articles/1/comments without having to purge
articles/1. For a RESTful web service, this proves to be tremendously useful.
Caching will reduce the number of requests hitting your origin server, as well as result in quicker response times for both consumer and internal APIs.
This tutorial will show you how to accomplish API caching with fastly-rails.
Before you can begin, you’ll need to configure a few things. Adding a new service requires that you specify the origin server, as well as the domain.
Next, you’ll need to point the
api.example.com.global.prod.fastly.net. This may take a moment to propagate.
It’s worth noting that Fastly uses Varnish under the hood. Services can use custom VCLs. Here’s an example:
One of the most powerful features of a custom VCL is the ability to serve stale content. Fastly has a tutorial available on the setup process, which I strongly suggest you enable.
To confirm that your setup is successful, run the following command:
You’ll notice that Fastly unique headers are present. Now it’s time to begin caching and purging dynamic content!
fastly-rails to your
Next, you’ll need to add an initializer:
To cache using
fastly-rails, you’ll need to set the
Cache-Control sets the time to live (TTL). The
before_action filter accomplishes this by calling the
set_cache_control_headers method before the
Surrogate-Key sets the surrogate key by calling the
set_surrogate_key_header method with an object’s
record_key. For example,
tags/1 for a single object and
tags for a collection.
We’ve all heard some variation of the following quote:
“There are only two hard things in Computer Science: cache invalidation, naming things and off-by-one errors.”
Despite it’s age, this quote is still surprisingly true. However, Fastly has managed to make cache invalidation much more pleasant.
There are multiple ways to purge content. Each approach takes advantage of the
#purge_all instance methods. For example, you can purge in your controller:
It’s worth noting that I’m not a fan of this approach. It can become difficult to maintain and it is not very DRY. In an effort to keep controllers as lean as possible, I would recommend purging using callbacks:
Rails offers before and after callbacks, which makes it much easier to just set it and forget it. In addition to programmatically purging, you can also use the Fastly dashboard. Purging can be as fast as 150 milliseconds, so it doesn’t really matter how you do it.
That’s it. You’ve successfully accomplished API caching with Fastly and Rails. Whether your API is public or private, it should now be much faster!