当使用circe对Json进行编码时,我们真的希望该type字段显示为例如
scala> val fooJson = foo.asJson
fooJson: io.circe.Json =
{
"this_is_a_string" : "abc",
"another_field" : 123,
"type" : "Foo"
}
Run Code Online (Sandbox Code Playgroud)
这取自之前提到您可以像下面这样配置编码的发行说明:
implicit val customConfig: Configuration =
Configuration.default.withSnakeCaseKeys.withDefaults.withDiscriminator("type")
Run Code Online (Sandbox Code Playgroud)
也谈瑟茜其他信息在这里表明,如果没有任何配置,你应该得到的编码JSON一些类的类型信息.
我错过了什么吗?你如何得到类型显示?
更新30/03/2017:跟进OP的评论
我能够完成这项工作,如链接的发行说明中所示.
准备步骤1:为build.sbt添加额外的依赖项
libraryDependencies += "io.circe" %% "circe-generic-extras" % "0.7.0"
Run Code Online (Sandbox Code Playgroud)
准备步骤2:设置虚拟密封特征层次结构
import io.circe.{ Decoder, Encoder }
import io.circe.parser._, io.circe.syntax._
import io.circe.generic.extras.Configuration
import io.circe.generic.extras.auto._
import io.circe.generic.{ semiauto => boring } // <- This is the default generic derivation behaviour
import io.circe.generic.extras.{ semiauto => fancy } // <- This is the new generic derivation behaviour
implicit val customConfig: Configuration = Configuration.default.withDefaults.withDiscriminator("type")
sealed trait Stuff
case class Foo(thisIsAString: String, anotherField: Int = 13) extends Stuff
case class Bar(thisIsAString: String, anotherField: Int = 13) extends Stuff
object Foo {
implicit val decodeBar: Decoder[Bar] = fancy.deriveDecoder
implicit val encodeBar: Encoder[Bar] = fancy.deriveEncoder
}
object Bar {
implicit val decodeBar: Decoder[Bar] = boring.deriveDecoder
implicit val encodeBar: Encoder[Bar] = boring.deriveEncoder
}
Run Code Online (Sandbox Code Playgroud)
使用此实际代码:
val foo: Stuff = Foo("abc", 123)
val bar: Stuff = Bar("xyz", 987)
val fooString = foo.asJson.noSpaces
// fooString: String = {"thisIsAString":"abc","anotherField":123,"type":"Foo"}
val barString = bar.asJson.noSpaces
// barString: String = {"thisIsAString":"xyz","anotherField":987,"type":"Bar"}
val bar2 = for{
json <- parse(barString)
bar2 <- json.as[Stuff]
} yield bar2
// bar2: scala.util.Either[io.circe.Error,Stuff] = Right(Bar(xyz,987))
val foo2 = for{
json <- parse(fooString)
foo2 <- json.as[Stuff]
} yield foo2
// foo2: scala.util.Either[io.circe.Error,Stuff] = Right(Foo(abc,123))
Run Code Online (Sandbox Code Playgroud)
因此,如果您导入额外的依赖项(它Configuration来自哪里),它看起来像是有效的.
最后,作为旁注,似乎Circe的DESIGN.md和练习之间存在一些脱节,我真的很高兴.
原始答案: 我不确定这应该得到设计的支持.
隐式范围不应用于配置.许多人已经要求一种方法来配置通用编解码器派生,以使用例如类型字段作为密封特征层次结构的鉴别器,或者将蛇案例用于成员名称.argonaut-shapeless使用用户可以隐式提供的JsonCoproductCodec类型非常直接地支持这一点.
我不想批评这种方法 - 它完全是惯用的Scala,并且它在实践中经常运行良好 - 但我个人不喜欢使用隐式值进行配置,我希望在我100岁之前避免它%确信没有其他方法可以提供此功能.
这具体意味着什么:你可能永远不会看到一个不是类型类实例的隐式参数 - 即,它不是应用于模型中的类型的类型构造函数,并且通用编解码器派生的配置正在进行相对有限(与例如argonaut-shapedless相比),直到我们找到一种很好的方式来做类型标签或类似的事情.
特别是,customConfig: Configuration似乎正是最后一段引用的参数类型(例如,不是类型类实例的隐式参数)
我相信@ travis-brown或任何其他Circe的主要贡献者可以对此有所了解,以防实际上有这样做的方式 - 我会很高兴知道它!:)
| 归档时间: |
|
| 查看次数: |
1110 次 |
| 最近记录: |