JSON encoding of case classes with the same name in different packages
See original GitHub issueI’m working with a large collection of case classes that extend a sealed trait. In order to avoid naming collisions these case classes are grouped into different objects (they could also be grouped in packages).
For instance I have an object of type Tabs.OnCreated and another of type Windows.OnCreated. The JSON representation only contains the simple class name though, so it’s impossible to distinguish the two types. The decoder just creates an instance of the first type.
I know this is probably a very special case. Still I’m wondering if there’s a way to support that kind of structure in Circe. I guess we’d need something like the full class name as discriminator in the JSON representation.
Minimal example below:
import io.circe.parser.decode
import io.circe.syntax._
import io.circe.generic.auto._
sealed trait Event
object Tabs { // could also be package tabs, same result
case class OnCreated(id: String) extends Event
}
object Windows {
case class OnCreated(id: String) extends Event
}
object CirceEval extends App {
val tabOnCreated: Event = Tabs.OnCreated("tab created")
val tabOnCreatedJson = tabOnCreated.asJson.toString()
val decodedTabEvent = decode[Event](tabOnCreatedJson)
println(tabOnCreatedJson)
println(decodedTabEvent)
println(decodedTabEvent.map(_.getClass))
val windowOnCreated: Event = Windows.OnCreated("window created")
val windowOnCreatedJson = windowOnCreated.asJson.toString()
val decodedWindowEvent = decode[Event](windowOnCreatedJson)
println(windowOnCreatedJson)
println(decodedWindowEvent)
println(decodedWindowEvent.map(_.getClass))
}
Output:
{
"OnCreated" : {
"id" : "tab created"
}
}
Right(OnCreated(tab created))
Right(class CirceEval$Tabs$OnCreated)
{
"OnCreated" : {
"id" : "window created"
}
}
Right(OnCreated(window created))
Right(class CirceEval$Tabs$OnCreated)
Issue Analytics
- State:
- Created 7 years ago
- Comments:6 (4 by maintainers)
Top Results From Across the Web
How can I configure Circe to stop using nested class names ...
How can I configure Circe to stop using nested class names as key names in encoded JSON? ... I'm trying to encode a...
Read more >Encoding and Decoding Custom Types - Apple Developer
Encoding and Decoding Custom Types. Make your data types encodable and decodable for compatibility with external representations such as JSON. Overview.
Read more >JSON Handling - http4s
JSON Handling · Add the JSON support module(s) · Sending Raw JSON · Encoding case classes as JSON · Receiving Raw...
Read more >39 JSON in Oracle Database
By definition, textual JSON data is encoded using a Unicode encoding, either UTF-8 or UTF-16. You can use textual data that is stored...
Read more >How to serialize properties of derived classes with System ...
Learn how to serialize polymorphic objects while serializing to and deserializing from JSON in .NET.
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
I’d be inclined not to provide special support for this case, since Shapeless’s generic representation doesn’t include the necessary information, and since there are potentially lots of ways the discriminator key could be chosen. Writing explicit instances for the top level isn’t too bad:
What do you think?
I’m going to go ahead and close this since I don’t want to stray too far from Shapeless’s generic representation for the basic case, and since master now supports transforming the constructor name via implicit configuration after #648 / #684.