To improve the response time of GET requests, JR can cache the generated JSON fragments for Resources which are suitable. First, set
config.resource_cache to an ActiveSupport cache store:
Then, on each Resource you want to cache, call the
See the caveats section below for situations where you might not want to enable caching on particular Resources.
The Resource model must also have a field that is updated whenever any of the model’s data changes. The default Rails timestamps handle this pretty well, and the default cache key field is
updated_at for this reason. You can use an alternate field (which you are then responsible for updating) by calling the
If context affects the content of the serialized result, you must define a class method
attribute_caching_context on that Resource, which should return a different value for contexts that produce different results. In particular, if the
fetchable_fields methods, or any method providing the actual content of an attribute, changes depending on context, then you must provide
attribute_caching_context. The actual value it returns isn’t important, what matters is that the value must be different if any relevant part of the context is different.
- Models for cached Resources must update a cache key field whenever their data changes. However, if you bypass Rails and e.g. alter the database row directly without changing the
updated_atfield, the cached entry for that resource will be inaccurate. Also,
updated_atprovides a narrow race condition window; if a resource is updated twice in the same second, it’s possible that only the first update will be cached. If you’re concerned about this, you will need to find a way to make sure your models’ cache fields change on every update, e.g. by using a unique random value or a monotonic clock.
- If an attribute’s value is affected by related resources, e.g. the
spoken_languagesexample above, then changes to the related resource must also touch the cache field on the resource that uses it. The
belongs_torelation in ActiveRecord provides a
:touchoption for this purpose.
- JR does not actively clean the cache, so you must use an ActiveSupport cache that automatically expires old entries, or you will leak resources. The MemoryCache built in to Rails does this by default, but other caches will have to be configured with an
:expires_inoption and/or a cache-specific clearing mechanism.
- Similarly, if you make a substantial code change that affects a lot of serialized representations (i.e. changing the way an attribute is shown), you’ll have to clear out all relevant cache entries yourself. The simplest way to do this is to run
JSONAPI.configuration.resource_cache.clearfrom the console. You do not have to do this after merely adding or removing attributes; only changes that affect the actual content of attributes require manual cache clearing.
- If resource caching is enabled at all, then custom relationship methods on any resource might not always be used, even resources that are not cached. For example, if you manually define a
records_for_commentsmethod on a Resource that
has_many :comments, you cannot expect it to be used when caching is enabled, even if you never call
cachingon that particular Resource. Instead, you should use relationship name lambdas.
- The above also applies to custom
find_by_keymethods. Instead, if you are using resource caching anywhere in your app, try overriding the
find_recordsmethod to return an appropriate
- Caching relies on ActiveRecord features; you cannot enable caching on resources based on non-AR models, e.g. PORO objects or singleton resources.
- If you write a custom
ResourceSerializerwhich takes new options, then you must define
config_descriptionto include those options if they might impact the serialized value: