You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: README.md
+132-8Lines changed: 132 additions & 8 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -51,6 +51,8 @@ backed by ActiveRecord models or by custom objects.
51
51
*[Routing] (#routing)
52
52
*[Nested Routes] (#nested-routes)
53
53
*[Authorization](#authorization)
54
+
*[Resource Caching] (#resource-caching)
55
+
*[Caching Caveats] (#caching-caveats)
54
56
*[Configuration] (#configuration)
55
57
*[Contributing] (#contributing)
56
58
*[License] (#license)
@@ -1644,10 +1646,11 @@ class DefaultValueFormatter < JSONAPI::ValueFormatter
1644
1646
class << self
1645
1647
def format(raw_value)
1646
1648
case raw_value
1647
-
when String, Integer
1648
-
return raw_value
1649
+
when Date, Time, DateTime, ActiveSupport::TimeWithZone, BigDecimal
1650
+
# Use the as_json methods added to various base classes by ActiveSupport
1651
+
return raw_value.as_json
1649
1652
else
1650
-
return raw_value.to_s
1653
+
return raw_value
1651
1654
end
1652
1655
end
1653
1656
end
@@ -1680,16 +1683,14 @@ resource for a system wide change).
1680
1683
and
1681
1684
1682
1685
```ruby
1683
-
class MyDefaultValueFormatter < JSONAPI::ValueFormatter
1686
+
class MyDefaultValueFormatter < DefaultValueFormatter
1684
1687
class << self
1685
1688
def format(raw_value)
1686
1689
case raw_value
1687
-
when String, Integer
1688
-
return raw_value
1689
1690
when DateTime
1690
-
return raw_value.in_time_zone('UTC').to_s
1691
+
return super(raw_value.in_time_zone('UTC'))
1691
1692
else
1692
-
return raw_value.to_s
1693
+
return super
1693
1694
end
1694
1695
end
1695
1696
end
@@ -1905,6 +1906,106 @@ Currently `json-api-resources` doesn't come with built-in primitives for authori
1905
1906
1906
1907
Refer to the comments/discussion [here](https://github.com/cerebris/jsonapi-resources/issues/16#issuecomment-222438975) for the differences between approaches
1907
1908
1909
+
### Resource Caching
1910
+
1911
+
To improve the response time of GET requests, JR can cache the generated JSON fragments for
1912
+
Resources which are suitable. First, set `config.resource_cache` to an ActiveSupport cache store:
1913
+
1914
+
```ruby
1915
+
JSONAPI.configure do |config|
1916
+
config.resource_cache = Rails.cache
1917
+
end
1918
+
```
1919
+
1920
+
Then, on each Resource you want to cache, call the `caching`method:
1921
+
1922
+
```ruby
1923
+
class PostResource < JSONAPI::Resource
1924
+
caching
1925
+
end
1926
+
```
1927
+
1928
+
See the caveats section below for situations where you might not want to enable caching on particular
1929
+
Resources.
1930
+
1931
+
TheResource model must also have a field that is updated whenever any of the model's data changes.
1932
+
The default Rails timestamps handle this pretty well, and the default cache key field is `updated_at` for this reason.
1933
+
You can use an alternate field (which you are then responsible for updating) by calling the `cache_field` method:
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 `meta` or `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
1955
+
returns isn't important, what matters is that the value must be different if any relevant part of the context is different.
*Modelsfor cached Resources must update a cache key field whenever their data changes. However, if you bypass Railsand e.g. alter the database row directly without changing the `updated_at` field, the cached entry for that resource will be inaccurate. Also, `updated_at` provides 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.
1988
+
* If an attribute's value is affected by related resources, e.g. the `spoken_languages` example above, then changes to the related resource must also touch the cache field on the resource that uses it. The`belongs_to` relation inActiveRecord provides a `:touch` option for this purpose.
1989
+
*JR does not actively clean the cache, so you must use an ActiveSupport cache that automatically expires old entries, or you will leak resources. TheMemoryCache built in to Rails does this by default, but other caches will have to be configured with an `:expires_in` option and/or a cache-specific clearing mechanism.
1990
+
*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.clear` from 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.
1991
+
* 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 `comments` method or `records_for_comments` method on a Resource that `has_many :comments`, you cannot expect it to be used when caching is enabled, even if you never call `caching` on that particular Resource. Instead, you should use relationship name lambdas.
1992
+
* The above also applies to custom `find` or `find_by_key` methods. Instead, if you are using resource caching anywhere in your app, try overriding the `find_records` method to return an appropriate `ActiveRecord::Relation`.
1993
+
* Caching relies on ActiveRecord features; you cannot enable caching on resources based on non-AR models, e.g. PORO objects or singleton resources.
1994
+
* If you write a custom `ResourceSerializer` which takes new options, then you must define `config_description` to include those options if they might impact the serialized value:
0 commit comments