Playframework 2.3 with Scala 2.11 and Cache

Setup Cache in Scala 2.11 and Playframework 2.3 using Compile DI
While working on a project that still runs old scala 2. I found the need to cache a result from another service. So using the built-in cache solution from Play is good enough
Dependency Setup
According to the playframework docs You need to make sure the dependency is set in your build.sbt file
libraryDependencies ++= Seq(
cache,
...
)
Plugin setup
Initially we neeed to make sure we have the following line in our plugins.conf file which normally is located at src/conf
ehcacheplugin = enabled
Debug logging to make sure EhCache is being loaded
To confirm that the plugin is loading, you can set logging level to DEBUG in application.conf
logger.root = DEBUG
logger.play = DEBUG
logger.application = DEBUG
Compiled Dependency Injection
Given I'm using macwire as my DI, I thought that we needed to instantiate the play.api.cache.CacheAPI, however, while this is possible to make it available in your Module.
import play.api.cache.{CacheAPI, EhCachePlugin}
trait CoreModule {
lazy val cache: CacheAPI = app.plugin[EhCachePlugin].map(_.api).getOrElse {
throw new RuntimeException("EhCachePlugin not enabled")
}
lazy api = wire[ExternalApi]
}
Upon further look at the code repository, I found there is a Singleton Cache, that means I can use it directly in my service without the need to inject it in the servie.
Then I can do the following:
import play.api.cache.Cache
class ExternalApi(ws: WsClient) {
lazy val apiV1 = "api-v1-abc"
def apiCall(endpoint: String): Future[ApiResponse] = {...}
def getLatestTag(): Option[String] = {
val cacheKey = s"api-v-$apiV1"
Cache.getAs[String](cacheKey) match {
case Some(cachedTag) =>
Future.successful(Some(cachedtag))
case _ =>
apiCall("/api/v1/latest-tags")
.map{ resp =>
val tagId = resp.tagId
Cache.set(cacheKey, tagId, 5 * 60)
Some(tagId)
}
.recover { case e: Exception =>
logger.error("Error with latest-tag", e)
None
}
}
}
}
Finally, this simple implementation can be useful through all your endpoints to access external endpoints that might have some thresholds or rate-limits