Search code examples
scalaplay-json

Using different JsonNaming strategies for different case classes in scala play


I've got two different JSON messages that I want to turn into instances of case classes.

case class ThisThing(attributeOne: String)
case class ThatThing(attributeTwo: String)

implicit val config: Aux[Json.MacroOptions] = JsonConfiguration(SnakeCase)
implicit val thisThingFormat: OFormat[ThisThing] = Json.format[ThisThing]
implicit val thatThingFormat: OFormat[ThatThing]= Json.format[ThatThing]

I can now parse messages like:

val thisThing = Json.fromJson[ThisThing](Json.parse("{\"attribute_one\": \"hurray\"}"))

However, my ThatThing JSON messages are not snake cased, their attributes match the case class:

val thatThing = Json.fromJson[ThatThing](Json.parse("{\"attributeTwo\": \"hurray\"}"))

This gives an error, as it's looking for an attribute called attribute_two to map to attributeTwo.

How do I specify a naming strategy of SnakeCase for only certain case classes?


Solution

  • As any implicit, the configuration can be scoped:

    import play.api.libs.json._
    
    case class ThisThing(attributeOne: String)
    case class ThatThing(attributeTwo: String)
    
    implicit val thisThingFormat: OFormat[ThisThing] = {
      implicit val config = JsonConfiguration(JsonNaming.SnakeCase)
    
      Json.format[ThisThing]
    }
    
    implicit val thatThingFormat: OFormat[ThatThing] = Json.format[ThatThing]
    

    Then:

    Json.fromJson[ThisThing](Json.parse("{\"attribute_one\": \"hurray\"}"))
    // res0: play.api.libs.json.JsResult[ThisThing] = JsSuccess(ThisThing(hurray),)
    
    Json.fromJson[ThatThing](Json.parse("{\"attributeTwo\": \"hurray\"}"))
    // res1: play.api.libs.json.JsResult[ThatThing] = JsSuccess(ThatThing(hurray),)