Awaitable http(s) request in Nodejs and Pulumi

Pulumi is a great tool for quick and easy deployment to cloud. It provides nice abstraction above several cloud providers, such as AWS, Kubernetes or Azure. But it also has some drawbacks. The biggest plus is that you can define your lambdas, tasks etc in single index.js file and import dependencies from other npm packages. Pulumi will then gather all those dependencies and compile then into single script. That script is then deployed to the could.

The drawback is that Pulumi can not compile some native functions, such as [Symbol.iterator]. When you rely on some 3rd party npm package, which iterates with the help of Symbol.iterator, Pulumi will not be able to compile it. (Unfortunately, I can’t google that error, but I’ve encountered it several times.)

My case was that I wanted to use async/await together with sending https request in nodejs. I’ve tried several npm packages which worked locally, but did not work in Pulumi. So after long struggle I came up with my own promise-based wrapper around http(s) requests. Feel free to use it. If you find it useful, please let me know in the comments.

const https = require("https");

module.exports.sendHttpsRequest = function(options, payload) {
 
    return new Promise(function (resolve, reject) {
        try {
 
            let body = [];
            const request = https.request(options, function (res) {
 
                if (res.statusCode != 200) {
                    reject(res.statusCode);
                }
 
                res.on('data', (data) => {
                  body.push(data);
                });

                res.on('end', () => {
                    // at this point, `body` has the entire request body stored in it as a string
                    let result = Buffer.concat(body).toString();
                    resolve(result);
                    return;
                });

                res.on('error', async (err) => {
                    console.error('Errooooorrrr', err.stack);
                    console.error('Errooooorrrr request failed');
                    reject(err);
                    return;
                });     
            });
 
            if (payload) {
                request.write(payload);
            };
 
            request.end();
        }
        catch (e) {
            console.log('Something unexpected', e);
        } 
    });
 }

Example of usage

async function testRequest() {
    const url = 'flickr.photos.search';

    const flickrResponse = await sendHttpsRequest({
        host: 'api.flickr.com',
        path: url,
        method: 'GET'
    }, null);

    return JSON.parse(flickrResponse);
}

Happy coding!

pulumi-sticker