Search code examples
jsonscalaplayframework-2.0

What is the purpose of Format[T] if you have a Reads[T] and Writes [T]?


I'm only hours into exploring the Play Framework (2.5.1) and I'm confused why you would create a Format when you've already defined Reads and Writes. By defining the Reads and Writes for your class, haven't you defined all the functionality needed to convert the class to and from JsValue?


Solution

  • As mentioned in the play-framework documentation here

    Format[T] is just a mix of the Reads and Writes traits and can be used for implicit conversion in place of its components.

    Format is a combination of Reads[T] and Writes[T]. So you can define a single implicit Format[T] for type T and use it to read and write Json instead of defining a separate implicit Reads[T] and Writes[T] for type T. Thus if you already have Reads[T] and Writes[T] defined for your type T then Format[T] is not required and vice versa.

    One advantage with Format is that you can define a single Implicit Format[T] for your type T instead of defining two separate Reads[T] and Writes[T] if they are both symmetrical (i.e. the Reads and Writes). So Format makes your JSON Structure definition less repetitive. For example you can do something like this

    implicit val formater: Format[Data] = (
        (__ \ "id").format[Int] and
        (__ \ "name").format[String] and
        (__ \ "value").format[String]
      ) (Data.apply, unlift(Data.unapply))
    

    Instead of this.

    implicit val dataWriter: Writes[Data] = (
        (__ \ "id").write[Int] and
        (__ \ "name").write[String] and
        (__ \ "file_type").write[String]
      ) (Data.apply)
    
    implicit val dataWriter: Reads[Data] = (
        (__ \ "id").read[Int] and
        (__ \ "name").read[String] and
        (__ \ "file_type").read[String]
      ) (unlift(Data.unapply))