Search code examples
scalaplayframeworkplay-json

JSON format for Single property case classes


Given

case class Location(lat: Double, long: Double)
case class Resident(location: Location)

What is the easiest way of writing a JSON formatter for Resident

I am trying to use the FunctionalBuilder i.e

val residentFormats: Format[Resident] = (
(JsPath \ "location").format[Location]
) (Resident.apply, unlift(Resident.unapply))

but using it with a single property case class is turning out to be not easily possible. My subsequent attempts are tending to involve a lot of code than I think is necessary.

Would appreciate some pointers


Solution

  • Just use:

    object Resident {
      implicit val format: OFormat[Resident] = Json.format[Resident]
    }
    

    Or you can split definitions:

    object Resident {
      implicit val reads: Reads[Resident] = Json.reads[Resident]
      implicit val writes: OWrites[Resident] = Json.writes[Resident]
    }
    

    You can define reads and writes by yourself:

    object Resident {
      implicit val reads: Reads[Resident] = json => {
        (json \ "location").validate[Location].map(Resident(_))
      }
      implicit val writes: OWrites[Resident] = resident => Json.obj("localtion" -> resident.location)
    }
    

    Note: If you need to convert name from camelCase to underscore_keys, you can define implicit JsonConfiguration:

    object Resident {
      implicit val jsonConfig = JsonConfiguration(SnakeCase)
      implicit val format: OFormat[Resident] = Json.format[Resident]
    }