How to write JSON reads/writes and also ReactiveMongo handlers when case classes contain a generic type parameter?

61 Views Asked by At

In playframework I am trying to write the reads/writes for JSON, along with reactivemongo's BSON handlers for my case class:

import play.api.libs.json._
import reactivemongo.api.bson._

case class SomeThing[T](id: String, name: String, value: T)
object SomeThing {
  implicit val stWrites = Json.writes[SomeThing]
  implicit val stReads  = Json.reads[SomeThing]

  implicit val stHander = Macros.handler[SomeThing]
}

Because my case class as a type parameter T, I am getting this compile error currently:

class SomeThing takes type parameters

How can I solve this issue?

1

There are 1 best solutions below

1
gatear On

You need implicit polymorphic functions:

import play.api.libs.json._
import reactivemongo.api.bson._


case class SomeThing[T](id: String, name: String, value: T)

//defined as polymorphic functions
//type T in each case needs to be accompanied by some implicit evidence

implicit def stWrites[T: OWrites]: OWrites[SomeThing[T]] =
  Json.writes[SomeThing[T]]

implicit def stReads[T: Reads]: Reads[SomeThing[T]] =
  Json.reads[SomeThing[T]]

implicit def stHander[T: BSONDocumentHandler]: BSONDocumentHandler[SomeThing[T]] =
  Macros.handler[SomeThing[T]]


stReads[String] //this works because play has an implicit StringReads available

case class OtherThing()

stReads[OtherThing] //this doesn't work we need to define a Reads[OtherThing]

implicit val otReads: Reads[OtherThing] =
  Json.reads[OtherThing]

stReads[OtherThing] //now it works

Later Edit: I dropped the generic example