从两个不同的Json文件中获取数据,在Scala中创建Seq[Object]

8aqjt8rx  于 2023-03-23  发布在  Scala
关注(0)|答案(1)|浏览(137)

我有一个像这样的班级模型

final case class Appointment(id: Option[String] = None,
                             service: Option[String] = None,
                             start_at: Option[String] = None,
                             end_at: Option[String] = None,
                             entity: Option[String] = None,
                             status: Option[String] = None,              
                             beneficiary: Option[String] = None,
                            )

我从两个不同的API中得到了不同结构给予JSON的响应,第一个与我的类具有相同的结构,所以要获得它的数据,这就足够了:

object Appointment {

    implicit val jsonFormat: OFormat[Appointment] = Json.format[Appointment]
}

但第二个不同的是:

{
 data[
  {
    "id": 101643,
    "establishment": "some stablishment",
    "id_client": 125,
    "reservation_date": "2023-01-23",
    "date_start": "2023-01-23T05:00:00.000000Z",
    "date_end": "2023-01-23T05:00:00.000000Z",
    "service": "some service",
  }]
}

Here我找到了一个解决方案,当它是一种或另一种方法,但我需要一种方法来合并这两种方法。我不能改变我的类属性,也不能这样做:

object User {
  implicit val jsonReads: Reads[User] = (
    (JsPath \ "id").read[String] and
    (JsPath \ "username").read[String] and 
    (JsPath \ "profile_picture").read[String] and
    (JsPath \ "full_name").read[String]
  )(User.apply _)
}

因为我会破坏已经存在的实现。

注意我需要Seq[Appointment]

总结一下,我需要创建一个Seq[Appointment],使用第一个API或第二个API提供的信息,这两个API提供的响应具有不同的结构,第二个API提供的结构与我的class Appointment模型不同

yhived7q

yhived7q1#

利用orElse
它是Reads trait上的一个方法,允许你将多个Reads组合成一个“回退”链。如果第一个失败,它会尝试第二个。
为您希望支持的每种JSON格式创建一个单独的Reads,然后将它们组合在一起,创建一个支持所有格式的Reads
这样做的细节将取决于你的类是如何设计的。例如,它们是否共享一个共同的超类型?它们是否完全独立,但可以从一种类型转换到另一种类型?
比如你可能会

implicit val theOtherTypeReads: Reads[TheOtherAppointmentType] = /* ... */

implicit val appointmentReads: Reads[Appointment] = {
  val defaultReads = Json.reads[Appointment]
  val otherTypeReads = theOtherTypeReads.map(_.convertToAppointment)
  defaultTypeReads.orElse(otherTypeReads)
}

implicit val appointmentReads: Reads[Appointment] = {
  val subtype1Reads = Json.reads[AppointmentSubtype1]
  val subtype2Reads = Json.reads[AppointmentSubtype2]
  subtype1Reads orElse subtype2Reads
  // note, the Json.reads macro might already do this for you,
  // if `Appointment` is a sealed trait...
}

相关问题