What's the scope for routes
file to find implicit
s like PathBindable
or QueryStringBindable
?
For custom types, it's trivial to simply define them in companion object like the following:
case class Foo(data: String)
object Foo {
implicit val pathBinder: PathBindable[Foo] = ???
}
However, for existing types, it's unclear where to declare implicit to be found by routes
file since we cannot do any custom import
here.
So, What's the scope of implicits for routes file?
This doesn't directly answer the question, but it seems relevant...
You can include custom imports in the routes
file by adding to the routesImport
key in your build.sbt
For example:
import play.PlayImport.PlayKeys._
routesImport += "my.custom.package.Foo._"
That snippet is borrowed from a blog post I wrote a while ago entitled Using Play-Framework's PathBindable
we had a queryStringBindable that we needed to use and had a similar situation, we found this question which gave us a clue but the answer from colinjwebb is out of date.
Here's our example which goes from a string to an Option[LoginContext].
package controllers
import play.api.mvc.{Action, AnyContent, QueryStringBindable, Request}
...
object BindableLoginContext {
implicit def queryStringBindable(implicit stringBinder: QueryStringBindable[String]) = new QueryStringBindable[LoginContext] {
override def bind(key: String, params: Map[String, Seq[String]]): Option[Either[String, LoginContext]] =
for {
loginContextString <- stringBinder.bind(key, params)
} yield {
loginContextString match {
case Right(value) if value.toLowerCase == "web" => Right(LoginContexts.Web)
case Right(value) if value.toLowerCase == "api" => Right(LoginContexts.Api)
case _ => Left(s"Unable to bind a loginContext from $key")
}
}
override def unbind(key: String, loginContext: LoginContext): String = stringBinder.unbind(key, loginContext.toString)
}
}
To use it we needed to use the following import:
import play.sbt.routes.RoutesKeys
and then add the object to the Project like this
lazy val microservice = Project(appName, file("."))
.settings(
RoutesKeys.routesImport += "controllers.BindableLoginContext._"
)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With