Vidya
Vidya

Reputation: 30310

Key-Based Caching in Play Framework with Scalaz Involved

I am attempting to do some key-based caching for my Play Framework application. Here is the code for the handler at my endpoint:

optionT(findById(id)).map { thing =>
      val cacheKey = thingCacheKey(thing)
      cached(cacheKey) {
        Action.async { implicit request =>
          val result = //Produce a result—probably Ok(“content”)
          } yield result    
        }
      }
}.run.map {
  case Some(actionF) => actionF
  case None => Action.async(Future.successful(NotFound()))
}

As you can see, I am using Scalaz's optionT monad transformer.

Not terribly surprisingly, I get this error:

Cannot use a method returning scala.concurrent.Future[play.api.mvc.EssentialAction] as a Handler for requests

Can you show me how to return a Result rather than EssentialAction with this approach?

Upvotes: 0

Views: 80

Answers (1)

Odomontois
Odomontois

Reputation: 16308

Play cache api has not any monadic composers nor has it Action so really need to run actions up to Iteratee which has flatten method that could unwrap this Future. This is example of successfully compiled approach

Action.async { implicit request => Iteratee.flatten {
  optionT(findById(id)).map { thing =>
    val cacheKey = thingCacheKey(thing)
    val action = cached(cacheKey) {
      Action.async{
        Future(Ok)   // replace with your processing of "request"
      }
    }

    action.apply(request)
  }.getOrElse(Iteratee.ignore[Array[Byte]].map(_ => NotFound))
}.run
}

Here we unwrapping OptionT transformer via getOrElse, not via run.map{ }, and then running Iteratee to Future[Result]

Upvotes: 1

Related Questions