How to parse deeply nested JSON in Scala with Monocle (Lens)

134 Views Asked by At

I've read an example on how to use monocle to parse some deeply jsons but the example its kind of straight forward, but I've a more difficulty one that looks like this:

{
"products": {
  "HY3BZPP2B6K8MSJF" : {
    "sku" : "HY3BZPP2B6K8MSJF",
    "productFamily" : "Storage",
    "attributes" : {
        "servicecode" : "AmazonEC2",
        "location" : "US East (N. Virginia)",
        "locationType" : "AWS Region",
        "storageMedia" : "SSD-backed",
        "volumeType" : "General Purpose",
        "maxVolumeSize" : "16 TiB",
        "maxIopsvolume" : "16000",
        "maxIopsBurstPerformance" : "3000 for volumes <= 1 TiB",
        "maxThroughputvolume" : "250 MiB/s",
        "usagetype" : "EBS:VolumeUsage.gp2",
        "operation" : "",
        "servicename" : "Amazon Elastic Compute Cloud",
        "volumeApiName" : "gp2"
    }
  },
  ...
 },
 "terms" : {
   "OnDemand" : {
      "HY3BZPP2B6K8MSJF" : {
         "HY3BZPP2B6K8MSJF.JRTCKXETXF" : {
           "offerTermCode" : "JRTCKXETXF",
           "sku" : "HY3BZPP2B6K8MSJF",
           "effectiveDate" : "2021-10-01T00:00:00Z",
           "priceDimensions" : {
              "HY3BZPP2B6K8MSJF.JRTCKXETXF.6YS6EN2CT7" : {
                "rateCode" : "HY3BZPP2B6K8MSJF.JRTCKXETXF.6YS6EN2CT7",
                "description" : "$0.10 per GB-month of General Purpose SSD (gp2) provisioned storage - US East (Northern Virginia)",
                "beginRange" : "0",
                "endRange" : "Inf",
                "unit" : "GB-Mo",
                "pricePerUnit" : {
                    "USD" : "0.1000000000"
                },
                "appliesTo" : [ ]
            }
        },
        "termAttributes" : { }
    }
 },
 ...
}

I can parse it using the following code:

val productData = productConnector.getProducts(100).map(p => Serializer.fromJson[ProductInfo](p))

but I don't know how to write a lens so I can create a Map with "volumeApiName" and the "pricePerUnit", something like (gp2 -> 0.1000000000) notice that the "volumeApiName" has a "sku" that can use it to match later on on the "terms"."OnDemand"., and then get deeper into the pricePerUnit.

0

There are 0 best solutions below