Executing sync requests programmatically from a pre-request or test scripts

Hello Postman team,

We are using Postman to automate a broad number of requests. Sometimes we need to query an API programmatically, wait for its response, process it, and then proceed depending on what we have received. Most of the time these types of checks and requests are best made programmatically and do not warrant another request to be made in the collection as it is to be considered a dummy request and right now we have a lot of them for other reasons, so adding more is not an option as our collection would become bloated with dummy requests. Having said that, the async pm.sendRequest() isn’t cutting it in that case.

Is there a limitation as to why there’s still no possibility to send sync requests from scripts? I mean, before exiting Postman’s requests still have to wait for the pm.sendRequest() to finish anyway so we are blocked during its execution, still, we are limited by the async pm.sendRequest() working, well … async, so it is useless when we want a strict flow of execution in the scripts.

Thanks for your time in reading this. I’m looking forward to your reply.

PS: If I’ve missed something out, please forgive me. Advises would be much welcomed!

Best regards,
Tihomir

Hi @tmladenov_atos,

Is this just about control flow aesthetics and avoiding “callback hell”?

If so, you can use async/await style JavaScript syntax in the Postman Sandbox. It just requires a little hack. The Postman Sandbox detects open timeouts and intervals and awaits execution until they’re all cleared/resolved. If we use a dummy Interval object, we can use async/await to have a cleaner method of chaining asynchronous calls.

Example:

const _dummy = setInterval(() => {}, 300000);

function sendRequest(req) {
    return new Promise((resolve, reject) => {
        pm.sendRequest(req, (err, res) => {
            if (err) {
                return reject(err);
            }

            return resolve(res);
        })
    });
}

(async function main() {
    const result1 = await sendRequest('http://postman-echo.com/get');
    console.log('result1:', result1.code);

    const result2 = await sendRequest('http://postman-echo.com/get');
    console.log('result2:', result2.code);

    const result3 = await sendRequest('http://postman-echo.com/get');
    console.log('result3:', result3.code);

    clearInterval(_dummy)
})();

Hope this helps.

Best,

Kevin

5 Likes

Hi @kevin.swiber ,

You are absolutely correct, it’s all about flow control and avoiding the callback mess. :grimacing:
Yesterday I’ve tried to use Promise, but I didn’t know about the trick on using timeouts and intervals, so the requests executed one after the other, async / await, but still, they were async and broke the execution flow.

So, that’s clearly some insider knowledge right there, which is much welcomed!

Thanks a lot, Kevin!

Thanks @kevin.swiber, this solution was very useful in solving Issue #9715. Apparently the second await never fired because the sandbox had already terminated by the time the first request was finished. This would also explain the strange behavior noted in Example 3 of that issue.

Thanks for this @kevin.swiber ,

Can I please ask a noob question?

I’ve placed an assertion inside the main() function however it doesn’t seem to trigger Postman’s test failure. Is there a way to do this?

Thank you

(async function main() {

    const result1 = await sendRequest('http://postman-echo.com/get');

    console.log('result1:', result1.code);

    const result2 = await sendRequest('http://postman-echo.com/get');

    console.log('result2:', result2.code);

    const result3 = await sendRequest('http://postman-echo.com/get');

    console.log('result3:', result3.code);

    pm.expect(5).to.eql(3); // this doesn't cause the test to fail

    clearInterval(_dummy)

})();

Hey @damiensawyer,

Not a noob question at all!

In fact, test failures are raised using JavaScript errors, and the Postman sandbox does not propagate errors that are thrown in this context. The method for taking advantage of async/await that’s outlined in the above post is a hack and workaround. This is one of the drawbacks and why you might want to settle for nested callbacks instead.

Hope that helps.

Best,

Kevin

Thanks @kevin.swiber, that’s helpful.

I have to say, I’ve been diving deep into the Postman test tools for the first time. They’re amazing!

I recently wrote something that might just solve it for you - callbacks need to be used but still it just makes the job half-way easier with this IMO: Async Operations!

Thank you Sivcan, that’s great :slight_smile:

Update: As of Postman v10.6.7, this bug has been fixed, and the workaround is no longer required!

If you’re interested in the technical details behind the fix, it was made in the open source postman-sandbox repo, available here: Support Promise execution in the sandbox. by kevinswiber · Pull Request #872 · postmanlabs/postman-sandbox · GitHub

1 Like