cache
Wraps its inner Route with caching support using the given spray.caching.Cache
implementation and
the in-scope keyer function.
Signature
def cache(cache: Cache[CachingDirectives.RouteResponse])
(implicit keyer: CacheKeyer, factory: ActorRefFactory): Directive0
The signature shown is simplified, the real signature uses magnets. [1]
The routeCache
constructor for caches:
def routeCache(maxCapacity: Int = 500, initialCapacity: Int = 16, timeToLive: Duration = Duration.Inf,
timeToIdle: Duration = Duration.Inf): Cache[RouteResponse] =
LruCache(maxCapacity, initialCapacity, timeToLive, timeToIdle)
[1] | See The Magnet Pattern for an explanation of magnet-based overloading. |
Description
The directive tries to serve the request from the given cache and only if not found runs the inner route to generate a
new response. A simple cache can be constructed using routeCache
constructor.
The directive is implemented in terms of cachingProhibited and alwaysCache. This means that clients
can circumvent the cache using a Cache-Control
request header. This behavior may not be adequate depending on your
backend implementation (i.e how expensive a call circumventing the cache into the backend is). If you want to force all
requests to be handled by the cache use the alwaysCache directive instead. In complexer cases, e.g. when the
backend can validate that a cached request is still acceptable according to the request Cache-Control header the
predefined caching directives may not be sufficient and a custom solution is necessary.
Note
Caching directives are not automatically in scope, see Usage about how to enable them.
Example
var i = 0
val route =
cache(routeCache()) {
complete {
i += 1
i.toString
}
}
Get("/") ~> route ~> check {
responseAs[String] === "1"
}
// now cached
Get("/") ~> route ~> check {
responseAs[String] === "1"
}
Get("/") ~> route ~> check {
responseAs[String] === "1"
}