Reputation: 31546
I have the following object which I am serializing to json using Circe
case class Person(name: String, data: String)
val x = Person("test", s"""{"a": 10, "b":"foo"}""")
import io.circe._, io.circe.generic.auto._, io.circe.parser._, io.circe.syntax._
println(x.asJson)
The output of the statement above is
{
"name" : "test",
"data" : "{\"a\":10, \"b\":\"foo\"}"
}
but the output I want is
{
"name": "test",
"data": {
"a": 10,
"b": "foo"
}
}
I get the data for the data field from a json based data store. I want to pass it through (so I don't want to unmarshall it into a scala object, only to demarshall it again into json. that marshall/demarshall is a waste of CPU on my server.
So how do I handle such data?
Upvotes: 2
Views: 897
Reputation: 27535
Well, you can write your own Encoder
implementation, e.g.:
import io.circe.{Encoder, Json}
import io.circe.jawn.parse
case class Person(name: String, data: String)
implicit val personEncoder: Encoder[Person] = new Encoder[Person] {
override def apply(person: Person): Json = {
val name = Json.fromString(person.name)
val data = parse(person.data) match {
case Left(_) => Json.obj()
case Right(value) => value
}
Json.obj("name" -> name, "data" -> data)
}
}
As a matter of the fact, you have pretty unusual case - one of the fields is a String
, that you need to parse, before you put it as a child Json node. Error failure need to be handled somehow - I used empty object, but that isn't necessarily what you would like to use.
If you want to omit the deserialization step... that is not possible. You are building tree of JSON nodes with defined behavior. String cannot suddenly be treated like Json
object.
Upvotes: 3