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
}
}
}
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With