Getting Started
Imports
At the very least you will need to import the ScalaCache API.
import scalacache._
Note that this import also brings a bunch of useful implicit magic into scope.
Create a cache
You’ll need to choose a cache implementation. If you want a high performance in-memory cache, Caffeine is a good choice. For a distributed cache, shared between multiple instances of your application, you might want Redis or Memcached.
Let’s go with Memcached for this example, assuming that there is a Memcached server running on localhost.
The constructor takes a type parameter, which is the type of the values you want to store in the cache.
import scalacache.memcached._
// We'll use the binary serialization codec - more on that later
import scalacache.serialization.binary._
final case class Cat(id: Int, name: String, colour: String)
implicit val catsCache: Cache[Cat] = MemcachedCache("localhost:11211")
Note that we made the cache implicit
so that the ScalaCache API can find it.
Basic cache operations
scala> val ericTheCat = Cat(1, "Eric", "tuxedo")
ericTheCat: Cat = Cat(1,Eric,tuxedo)
scala> val doraemon = Cat(99, "Doraemon", "blue")
doraemon: Cat = Cat(99,Doraemon,blue)
scala> // Choose the Try mode (more on this later)
| import scalacache.modes.try_._
import scalacache.modes.try_._
scala> // Add an item to the cache
| put("eric")(ericTheCat)
res3: scala.util.Try[Any] = Success(())
scala> // Add an item to the cache with a Time To Live
| import scala.concurrent.duration._
import scala.concurrent.duration._
scala> put("doraemon")(doraemon, ttl = Some(10.seconds))
res5: scala.util.Try[Any] = Success(())
scala> // Retrieve the added item
| get("eric")
res7: scala.util.Try[Option[Cat]] = Success(Some(Cat(1,Eric,tuxedo)))
scala> // Remove it from the cache
| remove("doraemon")
res9: scala.util.Try[Any] = Success(())
scala> // Flush the cache
| removeAll[Cat]()
res11: scala.util.Try[Any] = Success(())
scala> // Wrap any block with caching: if the key is not present in the cache,
| // the block will be executed and the value will be cached and returned
| val result = caching("benjamin")(ttl = None) {
| // e.g. call an external API ...
| Cat(2, "Benjamin", "ginger")
| }
result: scala.util.Try[Cat] = Success(Cat(2,Benjamin,ginger))
scala> // If the result of the block is wrapped in an effect, use cachingF
| val result = cachingF("benjamin")(ttl = None) {
| import scala.util.Try
| Try {
| // e.g. call an external API ...
| Cat(2, "Benjamin", "ginger")
| }
| }
result: scala.util.Try[Cat] = Success(Cat(2,Benjamin,ginger))
scala> // You can also pass multiple parts to be combined into one key
| put("foo", 123, "bar")(ericTheCat) // Will be cached with key "foo:123:bar"
res16: scala.util.Try[Any] = Success(())