serialize option None field on a object as json null
wenhoujx opened this issue ยท 7 comments
hello i found closed ticket #70 which concludes with "None fields on an object is dropped", however my use case actually asks for those null
to be present.
For example, the following test fails.
I wonder if there is a way to configure the null
encoding behavior. ๐
case class Foo(bar: Option[Bar])
case class Bar(baz: Option[String])
test("test encoding null") {
assertTrue(Foo(Some(Bar(baz=None))).toJson == """{"bar":{"baz":null}}""")
}
btw, i also found #638, which has a OptionAsJsonNull
wrapper. But i don't control all of the classes to be JSON serialized, so i don't think this wrapper helps me.
@wenhoujx , could you explain the use case further? Usage of null
in Scala code is generally considered an anti-pattern.
@Andrapyre hi, i am not trying to use null
in scala, i am trying to use json null
.
encoding: Option None -> json null
decoding: json null -> Option None.
it's a good idea to not encoding json null
fields in a json object, however it's nice to be able to control that behavior.
we figured out we can use implicit codec, however this doesn't work for zio-json 0.2.0-M4, works on zio-json 0.6.2.
0.2.0-M4 is the last version for zio 1 ? is that LTS? if so i think there is a bug.
object JsonNull {
import zio.json._
import zio.json.ast._
import zio.json.internal._
implicit def explicitlyNullOption[A](implicit A: JsonEncoder[A]): JsonEncoder[Option[A]] = new JsonEncoder[Option[A]] {
def unsafeEncode(oa: Option[A], indent: Option[Int], out: Write): Unit = oa match {
case None => out.write("null")
case Some(a) => A.unsafeEncode(a, indent, out)
}
// This is the only override we need to produce the behavior, but
// unfortunately I did't see a clean way to pull the default
// JsonEncoder[Option[A]] and override only this. YMMV
override def isNothing(oa: Option[A]): Boolean = false
override final def toJsonAST(oa: Option[A]): Either[String, Json] =
oa match {
case None => Right(Json.Null)
case Some(a) => A.toJsonAST(a)
}
}
}
object Codecs {
import JsonNull.explicitlyNullOption // import this at implicit macro expansion.
lazy implicit val codecBar = DeriveJsonCodec.gen[Bar]
lazy implicit val codecFoo = DeriveJsonCodec.gen[Foo]
}
/bounty $100 for making it configurable in some nice and consistent way.
๐ $100 bounty โข ZIO
Steps to solve:
- Start working: Comment
/attempt #1085
with your implementation plan - Submit work: Create a pull request including
/claim #1085
in the PR body to claim the bounty - Receive payment: 100% of the bounty is received 2-5 days post-reward. Make sure you are eligible for payouts
Thank you for contributing to zio/zio-json!
Add a bounty โข Share on socials
Attempt | Started (GMT+0) | Solution |
---|---|---|
๐ข @987Nabil | #1100 |
๐ก @987Nabil submitted a pull request that claims the bounty. You can visit your bounty board to reward.
๐๐ @987Nabil has been awarded $100! ๐๐