'Connecting to locally-hosted REST API from AWS Lambda via Ngrok

I'm doing a school project whereby I am hosting a REST API on my local machine at localhost:8080, and then using ngrok to forward all requests to another site ie. https://1234-56-789-101-112.ap.ngrok.io to localhost:8080. Then, I plan to write an AWS Lambda trigger function using Nodejs to submit POST HTTP requests to the REST API upon logs being written to Cloudwatch.

However, none of my attempts to connect have worked thus far. I have tried several Lambda functions, i.e.

const zlib = require('zlib');
const https = require('https');

/**
 * 
 * @param {Object} options
 * @param {Object} data
 * @return {Promise}
 * */
function doRequest(options, data) {
    return new Promise((resolve, reject) => {
        const req = https.request(options, (res) => {
            res.setEncoding("utf8");
            let responseBody ="";
            
            res.on("data", (chunk) => {
                responseBody += chunk;
            });
            
            res.on("end", () => {
                resolve(JSON.parse(responseBody));
            });
        });
        
        req.on("error", (err) => {
            reject(err);
        });
        req.write(data);
        req.end();
    });
};

exports.handler = function(input, context) {
    var payload = Buffer.from(input.awslogs.data, 'base64');
    zlib.gunzip(payload, function(e, result) {
        if (e) { 
            context.fail(e);
        } else {
            result = JSON.parse(result.toString());
            const data = JSON.stringify({
                number1: 500,
                number2: 1000.1,
                string3: "RecordInfinity"});
                
            const options = {
                hostname: '5200-39-109-129-177.ap.ngrok.io',
                path: '/records',
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                    'Content-Length': data.length
                },
            };
            
            const response = doRequest(options, data);
            console.log("response", JSON.stringify(response)); 
            
            context.succeed();
        }
    });
}

This returned a completely empty JSON body; neither did Ngrok record any attempt to even call the site.

I also tried the following code, which returned an error logged in Cloudwatch stating that the URL was invalid:

exports.handler = function(input, context) {
    var payload = Buffer.from(input.awslogs.data, 'base64');
    zlib.gunzip(payload, function(e, result) {
        if (e) { 
            context.fail(e);
        } else {
            result = JSON.parse(result.toString());
           https.get('5200-39-109-129-177.ap.ngrok.io/records', res => {
                let data = [];
                const headerDate = res.headers && res.headers.date ? res.headers.date : 'No response date';
                console.log('Status Code: ', res.statusCode);
                console.log('Date: ', headerDate);
                
                res.on('data', chunk => {
                    data.push(chunk);
                });
                
                res.on('end', () => {
                    console.log('Response.ended: ');
                    console.log(result);
                });
            }).on('error', err => {
                console.log('Error: ', err.message);
            }); 
            
            context.succeed();
        }
    });
}

This returned the error below:

{ "errorType": "TypeError", "errorMessage": "Invalid URL", "code": "ERR_INVALID_URL", "input": "5200-39-109-129-177.ap.ngrok.io/records", "stack": [ "TypeError [ERR_INVALID_URL]: Invalid URL", " at new NodeError (node:internal/errors:371:5)", " at onParseError (node:internal/url:552:9)", " at new URL (node:internal/url:628:5)", " at request (node:https:339:32)", " at Object.get (node:https:387:15)", " at Gunzip.cb (/var/task/rwsTest.js:64:19)", " at Gunzip.zlibBufferOnEnd (node:zlib:161:10)", " at Gunzip.emit (node:events:520:28)", " at endReadableNT (node:internal/streams/readable:1346:12)", " at processTicksAndRejections (node:internal/process/task_queues:83:21)" ] }

I would appreciate any help resolving these problems, as well as any ideas to connect and submit HTTP requests to a locally-hosted REST API (with or without using Ngrok) from an AWS Lambda trigger function.



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source