How to use Tagged Type in Play routes file with Pathbindable

267 Views Asked by At

For a service that handle a lot of ided entities, I'm trying to have some strong typing. To achieve this I'm using a technique based on phantom types/tagged type as it can be found in shapeless or scalaz. (I don't want to use AnyVal because I really don't want to pay the cost of boxing/unboxing)

I've done a minimal exemple which hit the following compile error :

class type required but String with controllers.TestController.Tagged[controllers.MyId] found

Here are the files :

  • app/controllers/TestController.scala
package controllers

import javax.inject._

import controllers.TestController.TString
import play.api.mvc._

trait MyId

object TestController {

  trait Tagged[U]
  type TString[T] = String with Tagged[T]
  def TString[T](s: String) =  s.asInstanceOf[String with Tagged[T]]

  implicit def tStringPathBindable[T](implicit binder : PathBindable[String]) : PathBindable[TString[T]] =
    binder.transform(TString,identity)
}

@Singleton
class TestController @Inject() extends Controller {

  def index(id : TString[MyId]) = Action { implicit request =>
    Ok("")
  }

}
  • conf/routes

    GET /myroute/:id controllers.TestController.index(id : TString[MyId])

The build.sbt

name := """play-tag"""

lazy val root = (project in file(".")).enablePlugins(PlayScala)

scalaVersion := "2.11.11"

// Adds additional packages into conf/routes
play.sbt.routes.RoutesKeys.routesImport ++=
  Seq(
    "controllers.MyId",
    "controllers.TestController._"
  )
  • project/build.properties

    sbt.version=0.13.15

  • project/plugins.sbt

    addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.5.14")

Is there a way to fix this error ? if no what is the reason ? corollary question, what would be the best practice to achive what I'm trying to do ? For instance I'm not very happy with the fact that I'm exposing that the Id is composed of a string but I don't want to much boilerplate either as I have a lot of entities to deal with.

0

There are 0 best solutions below