I need to check for the existence of a YMD uri date param on every request, and, if exist, store it in the Request for later access in various parts of the application where implicit request has been made available.
Request interception seems an obvious choice:
https://github.com/playframework/Play20/wiki/ScalaInterceptors
However, I am not seeing a way to add to the Request (actually RequestHeader is what’s available), assume it’s read only/immutable.
I am able to add data to the Request via Action Composition; however, this approach is limited to the composed action, and not every action (why I’d like the above global Before Interceptor approach to somehow work). For example, an Authentiucated action wrapper allows me to store the logged in user’s id in the Request.
trait Secured {
private case class Success[A](uid: Int, r: Request[A]) extends WrappedRequest(r)
def Authenticated[A](p: BodyParser[A])
(f: Success[A] => Result)(implicit group: RoleGroup) = {
def apply(maybeUser: Option[String])(implicit r: Request[A]) = {
maybeUser map {id =>
Cache.orElse(group.to_s+"-"+id, 3600){
repo.user.get(id.int, group) map(_.active) getOrElse false
} fold ( onFail, f(Success(id.int, r)) )
}
}
I would like to do the same for a possible uri date param, but have it apply to all Actions, or, again, have it applied before the Play routes mechanism is triggered via global interceptor.
Ideas much appreciated, thanks
To simulate injecting arbitrary data into the Request, you can extend WrappedRequest:
and then create Action provider traits that return an instance of your custom request wrapper. For example, a base Task action could look like:
and then derive an Authenticated action from Task:
and then use in your controllers:
I could call the date manipulations functions on a per action basis, sure, but that would only apply to Action scope. How would I access the startDate in the template layer? I couldn’t, but with a custom request wrapper you can inject anything you want and easily reference the data anywhere. So instead of bringing play’s request into scope:
you reference your custom request wrapper:
Does the job quite nicely, global interception I have yet to find a use for (maybe re-route some legacy URIs, but nothing as powerful as the WrappedRequest approach)