1
votes

Need your help in transform a message like below using DataWeave 2.0.

If I have the following JSON payload of users, with a group and subgroup.

    [   
    {
        "GROUP": "GROUP_A",
        "SUBGROUPS": [{
            "NAME": "SUBGROUP A1",
            "USERS": "USER 1"
        }]
    }, {
        "GROUP": "GROUP_B",
        "SUBGROUPS": [{
            "NAME": "SUBGROUP B1",
            "USERS": "user 2"
        }, {
            "NAME": "SUBGROUP B2",
            "USERS": ["USER 3", "USER 4", "USER 5"]
        }]
    }
]

What would a DataWeave transformation look like to tranform the payload to something structured like the following:

[{
   "GROUP": "GROUP_A",
   "SUBGROUP": "SUBGROUP A1",
   "USER": "USER 1"
},  
{
   "GROUP": "GROUP_B",
   "SUBGROUP": "SUBGROUP B1",
   "USER": "USER 2"
}, {
   "GROUP": "GROUP_B",
   "SUBGROUP": "SUBGROUP B2",
   "USER": "USER 3"
}, {
   "GROUP": "GROUP_B",
   "SUBGROUP": "SUBGROUP B2",
   "USER": "USER 4"
}, {
   "GROUP": "GROUP_B",
   "SUBGROUP": "SUBGROUP B2",
   "USER": "USER 5"
}]

I was trying with flatten but that does not work.

Thanks for any help!

1

1 Answers

3
votes

A series of flatmap should do the trick (just a function that behind the scenes is wrapping a map with flatten). The only tricky part is that in your example it looks like SUBGROUPS can either be a string or an array of strings. To get a better idea of what you're doing with this, replace each flatmap with map. You'll see what the structure looks like, and why flattening it produces what you want. If you're new to functional programming like this, the map is basically a way to iterate over something - so what we're doing is iterating over each group, then all the subgroups in that group, and then all the users in the subgroup (if its an array). This creates an array of objects at each level we do a map. From there, we flatten it all down into a single array.

%dw 2.0
output application/json
---
payload flatMap (group) ->
    group.SUBGROUPS flatMap (subgroup) ->
        if (subgroup.USERS is Array)
            subgroup.USERS map (user) -> {
                GROUP: group.GROUP,
                SUBGROUP: subgroup.NAME,
                USER: user
            }
        else {
            GROUP: group.GROUP,
            SUBGROUP: subgroup.NAME,
            USER: subgroup.USERS
        }