Home > OS >  Scala Akka (un)marshalling nested Seq collections with Spray JSON
Scala Akka (un)marshalling nested Seq collections with Spray JSON

Time:10-03

I'm trying to use Spray JSON to marshall the 'Seq' collection below into a 'BidRequest' entity with the parameters as defined. The Seq collection is mostly nested, therefore some 'Seq' parameter fields also have variable collection types that need to be marshalled. Then after a computation, the aim is to unmarshall the results as an entity of 'BidResponse'.

What's the best approach to do this?

I'm using Akka-HTTP, Akka-Streams, Akka-Actor.

Seq collection:


      val activeUsers = Seq(
          Campaign(
              id = 1,
              country = "UK",
              targeting = Targeting(
                  targetedSiteIds = Seq("0006a522ce0f4bbbbaa6b3c38cafaa0f") 
                  ),
                  banners = List(
                      Banner(
                          id = 1,
                          src ="https://business.URLTV.com/wp-content/uploads/2020/06/openGraph.jpeg",
                          width = 300,
                          height = 250
                          )
                        ),
                  bid = 5d
                )
            )

BidRequest case class:

case class BidRequest(id: String, imp: Option[List[Impression]], site:Site, user: Option[User], device: Option[Device])

BidResponse case class:

case class BidResponse(id: String, bidRequestId: String, price: Double, adid:Option[String], banner: Option[Banner])

The other case classes:


case class Campaign(id: Int, country: String, targeting: Targeting, banners: List[Banner], bid: Double)
case class Targeting(targetedSiteIds: Seq[String])
case class Banner(id: Int, src: String, width: Int, height: Int)

case class Impression(id: String, wmin: Option[Int], wmax: Option[Int], w: Option[Int], hmin: Option[Int], hmax: Option[Int], h: Option[Int], bidFloor: Option[Double])
case class Site(id: Int, domain: String)
case class User(id: String, geo: Option[Geo])
case class Device(id: String, geo: Option[Geo])
case class Geo(country: Option[String])

I've so far tried using the code below but keep getting type mismatch errors:

import akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport._
import spray.json.DefaultJsonProtocol._

implicit val resFormat = jsonFormat2(BidResponse)
implicit val bidFormat = jsonFormat1(BidRequest)
implicit val cFormat = jsonFormat1(Campaign)
implicit val tFormat = jsonFormat1(Targeting)
implicit val bFormat = jsonFormat1(Banner)
implicit val iFormat = jsonFormat1(Impression)
implicit val sFormat = jsonFormat1(Site)
implicit val uFormat = jsonFormat1(User)
implicit val dFormat = jsonFormat1(Device)
implicit val gFormat = jsonFormat1(Geo)

CodePudding user response:

The reason why you are getting Type errors with Spray JSON is because you need to use the corresponding jsonFormatN method, depending on the number of parameters in the case class.

In your case:

implicit val resFormat = jsonFormat5(BidResponse)
implicit val bidFormat = jsonFormat5(BidRequest)
implicit val cFormat = jsonFormat1(Campaign)
implicit val tFormat = jsonFormat1(Targeting)
implicit val bFormat = jsonFormat4(Banner)
...
  • Related