Blankman
Blankman

Reputation: 266988

How should I use the cache API with futures

I want to use the built in playframework cache API but not sure how to cache this web service request when it has futures.

def getUser(username: String): Future[Option[User]] = {
  ws.url("...").get.map { response =>
    response.json.validate[User] match {
       case JsSuccess(user, _) => Some(user)
       case JsError(errors) => {
           // log errors
           None
       }
    }
  }
}

The cache key will just be the username for now.

How would I use the cache API here?

I wanted to use the getOrElse pattern:

val user: User = cache.getOrElse[User]("item.key") {
  User.findById(connectedUser)
}

But the Future and Option is confusing me on how to go about using it.

Upvotes: 0

Views: 675

Answers (1)

rethab
rethab

Reputation: 8413

I would do it like this:

def fromWebservice(username: String): Future[Option[User]] =
  ws.url("..").get.map(validate) // validate does the json validate thing

def getUser(username: String): Future[Option[User]] = 
  cache.getAs[User](username) match {
    case Some(x) =>
      Future.successful(Some(x))
    case None =>
      fromWebservice(username).map(_.map { user =>
        cache.set(username, user)
        x
      })
  }

As an aside, the Play cache API does not have an API that returns Futures, but they're working on it: https://github.com/playframework/playframework/issues/5912

Upvotes: 1

Related Questions