使用circe时如何在Scala中表示动态JSON密钥

时间:2019-01-08 14:00:45

标签: scala circe

我试图将以下JSON表示为Scala案例类:

/usr/local/bin/pip3

但是,我的JSON具有我在运行时不知道的动态密钥,我想使用circe进行编码/解码。我正在使用正确的方式使用Scala表示这一点?

     {
       "cars": {
          "THIS IS A DYNAMIC KEY 1": {
            "name": "bla 1",
          },
          "THIS IS A DYNAMIC KEY 2": {
            "name": "bla 2",
          }
          ...
      }

2 个答案:

答案 0 :(得分:5)

我认为您可以只使用Map[String, CarDetails]。然后,您的ADT将变为:

import io.circe.generic.JsonCodec

@JsonCodec
case class Cars(cars: Map[String, CarDetails])

@JsonCodec
case class CarDetails(name: String)

唯一棘手的地方可能是您需要至少有一个CarDetails对象,或者可接受零。 Circe确实支持cats.data.NonEmptyMap

答案 1 :(得分:2)

处理这种情况的最直接方法可能是将cars案例类的Cars成员更改为类似Map[String, CarDetails]的类型,将{{1 }}完全是case类。如果这样做,您的代码将按原样运行(减去Car定义),并将解码您提供的JSON示例。

如果您想要更接近案例类结构的内容,则可以执行以下操作:

Car

这将解码相同的JSON,但将在import io.circe.Decoder import io.circe.generic.JsonCodec case class Cars(cars: List[Car]) object Cars { implicit val decodeCars: Decoder[Cars] = Decoder[Map[String, CarDetails]].prepare(_.downField("cars")).map(kvs => Cars( kvs.map { case (k, v) => Car(k, v) }.toList ) ) } // I've added an `id` member here as a way to hold on to the JSON key. case class Car(id: String, whatShouldThisBe: CarDetails) @JsonCodec case class CarDetails(name: String) 级别包含动态密钥。