0
votes

I am using action composition of play framework 2.3 and I would like to send parameters to the custom action.

For example, if you have a custom action that adds a cache how the custom action can receive the cache key and the desired cache time. Example code inside a play controller:

def myAction(p1: String) = CachedAction(key="myAction1"+p1, time = 300.seconds) { 
 implicit request =>
... do an expensive calculation …
    Ok(views.html.example.template())
}

I have tested an ActionBuilder combined with a custom request but I haven't found a solution.

I am aware that play offers a cache for actions, unfortunately that cache does not meet all the requirements.

1

1 Answers

1
votes

I am not sure about solution with ActionBuilder or ActionRefiner but that may work for you:

def CachedAction(key: String, time: Duration)(f: Request[AnyContent] => Result) = {
  Action{ request =>
    if(cache.contains(key)){
      ...
    } else{
      ...
    }
    f(request)
  }
}

and then:

def myAction(p1: String) = CachedAction("hello" + p1, 100 millis){ request =>
  Ok("cached action")
}

Edit: Since you need Action.async you can write something like that:

case class Caching[A](key: String, time: Duration)(action: Action[A]) extends Action[A] {
    def apply(request: Request[A]): Future[Result] = {
      if(cache.contains(key)){
        Logger.info("Found key: " + key)
      }
      action(request)
    }
    lazy val parser = action.parser
}

def cached(p1: String) = Caching(key = p1, time = 100 millis){
    Action.async { Future(Ok("hello")) }
    //or
    Action { Ok("hello") }
}

Case class with two parameter lists looks weird but it works. Docs:https://www.playframework.com/documentation/2.3.x/ScalaActionsComposition#Composing-actions