I recently accomplished this by adding caches myself into PORO serializers that implement some JBuilder. Here’s the parts of one of mine that are relevant:
class ElectricConsumptionGraphDataSerializer
def as_json
Rails.cache.fetch(cache_key) do
Jbuilder.encode do |json|
json.time_zone time_zone
json.data measurements_as_hashes
end
end
end
private
def cache_key
{
serializer: self.class.to_s,
stat_record: stat_record.updated_at
}
end
end
If the stat record (which is the parent of the data related to the chart) has been updated, then Rails will generate new data when #fetch is called. The serializer’s cache key contains the class of the serializer’s class name because there are other serializers that rely on the stat record for their expiration, and I don’t want the different serializers to clobber each other in the cache.
If I were going to do this all over again, knowing that I have to cache these pieces, I think I’d it with Rabl and then use fragment caching in my Rabl templates, which makes it much easier to do nested, Russian-doll style caches where sub-components of the API response have their own caches. (You can probably do this in JBuilder as well, but I’ve soured a little bit on JBuilder’s API.) One of the nice things about Rabl is that you can lay out your API in a view template in a nice, clean way, so creating an API response isn’t much different than building an HTML view.