Search code examples
muletransformationdataweavemulesoftmule4

dataweave transformation


I have an input of the following payload for a POST method:

{
  "order": {
    "Column_X": "X",
    "Column_Y": "Y",
    "Column_Z": "Z",
    "Column_W" : {
      "div_1": "some text",
      "div_2": true,
      "div_3": 2
    }
  },
  "mapper": {
    "A": "<order.Column_X>",
    "B": "<order.Column_Z>",
    "C": "Fields or text not mapped to order",
    "C1": "status",
    "D": {
      "D1": "<order.Column_W.div_1>",
      "D2": "<order.Column_W.div_2>",
      "D3": "<order.Column_W.div_3>",
      "D4": "<order.Column_W.div_4>"
    }
  }
}

Here is the expected output mapping with the order object above:

{
   "A":"X",
   "B":"Z",
   "C":"Fields or text not mapped to order",
   "C1":"status",
   "D":{
      "D1":"some text",
      "D2":true,
      "D3":2,
      "D4":null
   }
}

How would I approach this to solve it?


Solution

  • To make it fully dynamic you need two things.

    1. A function that can fetch a value from a dynamic path
    2. Use recursion to build the payload since your mapper itself can contain more Objects that are mapper.
    %dw 2.0
    output application/json
    
    fun isPath(value) = (value is String) and (value matches "<.+>")
    
    fun getFromPath(json, pathString) = 
        pathString splitBy '.'
            reduce ((path, valueAtPath = json) -> valueAtPath[path])
    
    fun buildUsingMapper(mapper, mappingValues) = 
    mapper mapObject ((value, key) -> {
        (key): if(isPath(value)) mappingValues getFromPath value[1 to -2] // eliminate the first "<" and the ending ">". 
                else if(value is Object) buildUsingMapper(value, mappingValues)
                else value
    })
    ---
    buildUsingMapper(payload.mapper, payload - "mapper") // you can also pass the full payload instead of payload - "mapper". I did it here to show that the second parameter does not necessarily need the mapper object within.
    

    I have assumed there are no arrays that will have these dynamic path in mapper, Or the dynamic paths will include accessing an array element dynamically.