Motivation
We have trait Foo and two case classes that extends that trait
sealed trait Foo
case class Bar(i: Int) extends Foo
case class Baz(f: Float) extends Foo
What is json representation of Bar?
{
"i": 1
}
What's json representation of Bar with type?
{
"bar": {
"i" : 1
}
}
Notice: There are some libraries (like json4s) that would present 'bar' like:
{
"i": 1,
"$type": "bar"
}
Why i don't like $type attribute
- It's not obvious
- It's not gonna be readable if you compose complex class
sealed trait Foo
case class Bar(i: Int) extends Foo
case class Baz(f: Float) extends Foo
case class Complex(
foos: Foo,
foosList: List[Foo]
)
Json representation of Complex:
- Case with "$type"
{
"foo": {
"f": 3.14,
"$type": "baz"
},
"foosList": [
{
"i": 1,
"$type": "bar"
},
{
"f": 3.14,
"$type": "baz"
}
]
}
- Let's get rid of "$type" and move it as root property:
{
"foo": {
"baz": {
"f": 3.14
}
},
"foosList": [
{
"bar": {
"i": 1
},
"baz": {
"f": 3.14
}
}
]
}
How to accomplish this task with json_generic?
import com.github.kondaurovdev.json_generic._
import play.api.libs.json._
import com.github.kondaurovdev.play_json.helper.iValidateHelper
object Validate extends iValidateHelper
object iFoo extends iGenericDef[Foo] {
def validateHelper = Validate
object Names {
val BAR = "bar"
val BAZ = "baz"
val BAZ1 = "baz1"
}
val all = Stream(
nonEmptyGeneric(Names.BAR, Json.format[Bar]),
nonEmptyGeneric(Names.BAZ, Json.format[Baz]),
emptyGeneric(Names.BAZ1, Baz1())
)
}
trait iFoo extends iGenericCase {
def genericDef: iGenericDef[_] = iFoo
}
class Foo(val genericName: String) extends iFoo
case class Bar(i: Int) extends Foo(iFoo.Names.BAR)
case class Baz(f: Float) extends Foo(iFoo.Names.BAZ)
case class Baz1() extends Foo(iFoo.Names.BAZ1)