How to sort JSON request body keys including nested objects in alphabetical order and then stringify that object?

Hello.

I need an option in the Pre-request Script to sort my JSON request body keys alphabetically and also that should be done with nested objects and then stringify that object.

Only and only the keys (not values, arrays shouldn’t be touched ) of all objects (nested one too) inside needs to be sorted.

In Nodejs I use simply json-stable-stringify npm module that will do this function, but since postman doesn’t have that module in the sandbox.

Is there any other way to do that?

Hey @konsta.2106

Welcome to the community! :wave:

What have you got so far? Have you attempted to create something in the sandbox and are stuck with where to go next?

I did a quick search and found this that could be useful as a starting point, I don’t think that it’s doing the sorting against nested objects though.

I’ve been messing around with this in the app and have this sorting part of the request and logging that to the console.

let unorderedObj = JSON.parse(pm.request.body.raw),
    sortObjKeysAlphabetically = (obj) => Object.fromEntries(Object.entries(obj).sort());


console.log(sortObjKeysAlphabetically(unorderedObj));

Not exactly what you’re after but hopefully something to get you started but I’m sure folks with more JS experience would be able to offer a better solution.

Hi @konsta.2106,

Welcome to the community! :clap:

Just curious here, but can you explain the explicit reason you need your JSON keys alphabetically sorted? I ask because in the RFC spec that defines JSON, order of objects cannot be guaranteed, when traveling across the network.

While I’m not sure that comes off correctly (and I may be saying it somewhat incorrectly), order of your json attributes should not matter, because each client can order the data they way they want, regardless of how its sent.

In the end, the data hasn’t changed, and no functionality has changed about it, it’s just that order cannot be guaranteed by any specific client used, as they may (and likely will) differ in order.

If you can elaborate on the reason why you require order, we can certainly come up with a solution that should fit your needs :slight_smile:

Hello again.
@odanylewycz In our API, we use client secret and sorted request body object as a string for creating a signature. For now i found at least in my opinion working solution for postman that works exactly as our nodejs and python script for generating that signature.

const clientSecret = pm.environment.get("client_secret")
const bodyString = JSON.stringify(sortObject(requestBody))

function sortObject(unordered, sortArrays = false) {
    if (!unordered || typeof unordered !== 'object') {
        return unordered;
    }

    if (Array.isArray(unordered)) {
        const newArr = unordered.map((item) => sortObject(item, sortArrays));
        if (sortArrays) {
        newArr.sort();
        }
        return newArr;
    }

    const ordered = {};
    Object.keys(unordered)
        .sort()
        .forEach((key) => {
        ordered[key] = sortObject(unordered[key], sortArrays);
        });
    return ordered;
}

var hmac = CryptoJS.algo.HMAC.create(CryptoJS.algo.SHA256, clientSecret);
hmac.update(bodyString)
var hash = hmac.finalize();
var base64 = CryptoJS.enc.Base64.stringify(hash);
1 Like

Thanks for the explanation @konsta.2106. Sounds like fun :slight_smile:

In that case, then yes I can see the need for sorted JSON.

Glad you were able to get it working!