play.api.libs.json で複数の型を受け取る
多分もっと良いやり方ある。。。
例えば{id: "1", value: 1} とかあるとvalueはIntじゃないと受け取れないと。1だったり"1"が混合していると詰む。全部Stringにしたい。どうしたら良いか?くっそハマったのでメモを残しておきます。
これが変換ルールです。
readNullable(
Reads.of[String] or
Reads.of[Int].map(_.toString) or
Reads.of[Double].map(_.toString))
sample code
case class Hoge( id: String, nanika: Option[String], value: Option[String] ) object Hoge { implicit val rds: Reads[Option[String]] = (__ \ "value").readNullable( Reads.of[String] or Reads.of[Int].map(_.toString) or Reads.of[Double].map(_.toString)) implicit val wrs: OWrites[Option[String]] = (__ \ "value").writeNullable[String] implicit val formt: Format[Hoge] = ( (__ \ 'id).format[String] ~ (__ \ 'nanika).formatNullable[String] ~ (__).format(rds)(wrs) )(Hoge(_,_,_), unlift(Hoge.unapply)) }
ググってギリギリ見つけたのがofを使う方法で、ofとか解決できないんだけどどこにあるのと思いコードを見てみると、play.api.libs.json.Readsにplay.api.libs.json.ConstraintFormatがミックスインされて実装されていました。。 import play.api.libs.json.Reads._ したほうがReads.は省略できていいかもです。