scala の play で routes にcase object 使う
enumよりcase class
の方が良さそうだったので。
バージョンとか
- scalaVersion := "2.11.2"
- addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.3.7")
コード
- conf/routes
GET /foo controllers.Hoge.foo(device: controllers.Device)
- controllers/Hoge.scala
implicit定義
sealed abstract class Device {
val name = this.toString.toLowerCase
}
object Device {
case object Android extends Device
case object iOS extends Device
implicit def queryStringBinder = new QueryStringBindable[Device] {
override def bind(key: String, params: Map[String, Seq[String]]): Option[Either[String, Device]] = {
params(key).headOption map { deviceString =>
deviceString.toLowerCase match {
case Android.name => Right(Android)
case iOS.name => Right(iOS)
case _ => Left("Unable to bind a Device")
}
}
}
override def unbind(key: String, device: Device): String = {
device.name
}
}
}
actionのとこ
object Hoge extends Controller {
def foo(device: Device) = Action { request =>
println(device, device.getClass)
device match {
case Device.Android => println("ぐーぐる")
case Device.iOS => println("林檎")
}
Ok("OK")
}
}
挙動
- 200 おk
- curl -s -v "localhost:4080/foo?device=android"
- curl -s -v "localhost:4080/foo?device=ios"
- 400 Bad Request
- curl -s -v "localhost:4080/foo?device=andrd"
- curl -s -v "localhost:4080/foo?device=firefox"
- 500 Internal Server Error
- curl -s -v "localhost:4080/foo?devie=ios"
参考にしたとこ
主にこのへん。