Search code examples
jsonscalagenericsplay-json

Get a Json format for a Seq of a generic type


I have an abstract class with a generic type which gets a Json format for that generic type from its subclass. But the abstract class also needs a Json format of a sequence of that type. Is there any way in Scala to get a Json format of a sequence of things based only on the format of those things?

I'm using the Play Json framework.

Here's an example that doesn't follow my case exactly but provides a good indication of what I want to achieve:

  package scalatest

  import scala.concurrent.Future
  import scala.concurrent.ExecutionContext.Implicits.global
  import scala.concurrent.Await
  import scala.concurrent.duration.Duration
  import java.util.UUID
  import scala.util.control.NonFatal
  import play.api.libs.json.Format
  import play.api.libs.json.Json

  object Banana {

     def main(args: Array[String]): Unit = {
        val f: Format[Seq[Banana]] = getSeqFormat(Json.format[Banana])
     }

     def getSeqFormat[T](format: Format[T]): Format[Seq[T]] = {
        ??? // TODO implement
     }
  }

  case class Banana(color: String)

Solution

  • If you're just trying to serialize bananas into JSON objects then the only thing you need to do is define the Banana implicit json format, the others (like Seq format for example) are built-in within play:

    import play.api.libs.json.Json
    
    case class Banana(color: String)
    object Banana {
      implicit val jsonFormat = Json.writes[Banana]
    }
    
    object PlayJsonTest extends App {
      val bananas = Seq(Banana("yellow"), Banana("green"))
      println(Json.toJson(bananas)) // [{"color":"yellow"},{"color":"green"}]
    }
    

    This also works for other types because the Json#toJson method is defined as follows:

    // Give me an implicit `Writes[T]` and I know how to serialize it
    def toJson[T](o: T)(implicit tjs: Writes[T]): JsValue = tjs.writes(o)
    

    The defaults are implicitly used and those include a format for most of the collections. You can find them here.

    I hope that helps you.