Custom Encoder/Decoder to parse MongoDB Extended JSON

953 views Asked by At

I am trying to parse MongoDB Extended JSON using Circe JSON Parser, works fine in most of the cases except for special datatypes, for eg. in below case class i have priorityOrder which is of long datatype.

case class relinfo(id:String,assetId:String,insureeId:String,queue:String,priorityOrder:Long) extends baseDomain

But when it is converted to MongoDB JSON format, it is converted to special mongo format described below (check priorityOrder field)

{
  "_id" : "4abf009d-64b1-496c-b0e8-9061f5e183a0",
  "id" : "4abf009d-64b1-496c-b0e8-9061f5e183a0",
  "assetId" : "e26d5310-ab0c-4672-9971-4babd3420302",
  "insureeId" : "cdee05a1-a09c-4e10-81df-c3f112298cc3",
  "queue" : "Low",
  "priorityOrder" : {
    "$numberLong" : "1930926795621"
  }
}

The challenge is during de-serialization process, if i try to take this JSON and convert back to concrete object type using circe parser then it fails to map priorityOrder attribute, is there any way i can write custom encoder/decoder that will treat long data type in a special manner. The custom encoder/decoder will read value from "$numberLong" nested type and convert that value to Long datatype.

I get this exception from circe parser

Left(DecodingFailure(Long, List(El(DownField(priorityOrder),true,false))))
1

There are 1 answers

0
GammaVega On

I was able to figure out solution to this problem by creating custom decoder for long datatype. Here is the code for individuals in similar boat

  implicit val decodeLong: Decoder[Long] = new Decoder[Long] {
      final def apply(c: HCursor): Decoder.Result[Long] = 
        {
          val longval = c.downField("$numberLong").as[String] match 
          {
            case Right(x) => x.toLong
            case _ => throw new Exception("Unable to find $numberLong")
          }
          Right(longval)  
        }
  }