Scala reserved word as JSON field name with Json.writes[A] (Play equivalent for @SerializedName)
Asked Answered
S

1

6

I'm producing JSON with Play 2.4.3 & Scala in the following fashion, providing an implicit Writes[DeviceJson] created with Json.writes.

import play.api.libs.json.Json

case class DeviceJson(name: String, serial: Long, type: String)

object DeviceJson {
  implicit val writes = Json.writes[DeviceJson]
}

Of course, the above doesn't compile as I'm trying ot use the reserved word type as field name in the case class.

In this scenario, what is the simplest way to output JSON field names such as type or match that I can't use as Scala field names?

With Java and Gson, for example, using a custom JSON field name (different from the field name in code) would be trivial with @SerializedName annotation. Similarly in Jackson with @JsonProperty.

I know I can do this by rolling my own Writes implementation:

case class DeviceJson(name: String, serial: Long, deviceType: String)

object DeviceJson {
  implicit val writes = new Writes[DeviceJson] {
    def writes(json: DeviceJson) = {
      Json.obj(
        "name" -> json.name,
        "serial" -> json.serial,
        "type" -> json.deviceType
      )
    }
  }
}

But this is clumsy and repetitive, especially if the class has a lot of fields. Is there a simpler way?

Superintendent answered 1/12, 2015 at 10:8 Comment(0)
C
18

In your case class, you can use backtick for field name:

case class DeviceJson(name: String, serial: Long, `type`: String)

With this, your Writes should work

Colum answered 1/12, 2015 at 11:5 Comment(2)
Nice, thank you! I had to look it up; names like these are called literal identifiers.Superintendent
With a custom Jackson ObjectMapper in Play framework this does not seem to work. Any suggestions, is there some config value I have to supply to the ObjectMapper?Unreconstructed

© 2022 - 2024 — McMap. All rights reserved.