Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I configure Circe to stop using nested class names as key names in encoded JSON?

I'm trying to encode a case class (where some properties are also case classes), and I'm getting the nested case class name as the key name in the JSON. Is there a simple way to avoid that without creating a custom encoder? The nested classes inherit from a sealed trait.

I'm currently using semi-automatic derivation.

The following worksheet example shows my problem:

case class A(foo: Int, bar: Sub)

sealed trait Sub
case class B(x: Int, y: Int) extends Sub
case class C(x: Int, y: Int, z: Int) extends Sub

import io.circe._, io.circe.generic.semiauto._
import io.circe.syntax._

implicit val bEncoder: Encoder[Sub] = deriveEncoder
implicit val aEncoder: Encoder[A] = deriveEncoder

A(123, B(8, 8)).asJson
A(456, C(8, 8, 8)).asJson

Instead of getting:

res0: io.circe.Json = {
  "foo" : 123,
  "bar" : {
    "x" : 8,
    "y" : 8
  }
}
res1: io.circe.Json = {
  "foo" : 456,
  "bar" : {
    "x" : 8,
    "y" : 8,
    "z" : 8
  }
}

I'm getting

res0: io.circe.Json = {
  "foo" : 123,
  "bar" : {
    "B" : {
      "x" : 8,
      "y" : 8
    }
  }
}
res1: io.circe.Json = {
  "foo" : 456,
  "bar" : {
    "C" : {
      "x" : 8,
      "y" : 8,
      "z" : 8
    }
  }
}
like image 667
Steven Bakhtiari Avatar asked Aug 03 '18 11:08

Steven Bakhtiari


1 Answers

I ended up just creating my own encoder. The other option was to define a discriminator which could take the class name and set it as a property in the object, but I needed to create specific JSON without any additional properties. If somebody else comes along and wants to do this and doesn't mind having a 'type' property, the take a look at the Configuration class.

import io.circe.generic.extras.semiauto._
implicit val configuration: Configuration = 
  Configuration.default.withDiscriminator("type")
implicit val json: Encoder[FooBar] = deriveEncoder[FooBar]

Take note of the semiauto import from the extras package.

like image 151
Steven Bakhtiari Avatar answered Oct 12 '22 15:10

Steven Bakhtiari