Search code examples
circe

Modify field at any level with circe-optics


I am trying to transform the "model" field at any level with circe-optics and I'm having trouble in achieving this.

Input:

{
  "model":"ModelExample1",
  "test": {
    "model":"ModelExample2"
  }
}

Expected Ouput:

{
  "model":"AAAA-ModelExample1",
  "test": {
    "model":"AAAA-ModelExample2"
  }
}

Solution

  • Circe optics do not provide a recursive modification function out of the box. However, you can make one:

    import io.circe.optics.JsonPath._
    
    val modifyModel: Json => Json = root.model.string.modify("AAAA-" + _)
    
    def modifyAllModels(value: Json): Json =
        root.each.json.modify(modifyAllModels)(modifyModel(value))
    

    The modification will be applied to all keys, not just test - if you don't want that, swap each for test in modifyAllModels.