fabiojose
12/22/2016 - 4:58 PM

a nodejs api gateway

a nodejs api gateway

routing:
- path:
     origin: /api/projects
     route: /api/1/projects
     accept: application/json

- path:
     origin: /api/project/newp1
     route: /api/2/project/newp1/jobs
     accept: application/json

- path:
     origin: /api/job/uuid
     route: /api/1/job/b327f70d-6bf5-4ea7-bd2f-57bf629ac896
var http              = require('http');
var httpProxy         = require('http-proxy');
var parseUrl          = require('parseurl');
var yamlConfig        = require('yaml-configuration-loader');
var routes            = yamlConfig.load(__dirname + '/config/routing.yml');
var jsonRoutes        = JSON.parse(JSON.stringify(routes));
var util              = require('util');
var RUNDECK_SERVER    = "http://localhost:4440";
var RUNDECK_APITOKEN  = "HQzTl4zvZBakZMHg81IoJTnzAmjPL2si";
var NODE_PORT         = 3000;

var server = http.createServer(function (req, res) {
    var parsedUrl = parseUrl(req);
    console.log("PARSED_URL: ", parsedUrl.pathname);
    console.log("PARSED_QUERY: ", parsedUrl.search);

    var _write = res.write;

    res.write = function(data){
        console.log(data.toString());
        _write.call(res, data.toString());
    };

    var path = null;
    var routing = jsonRoutes.routing;
    for (var idx in routing) {
        console.log("PATH: ",  routing[idx].path);
        console.log("ORIGIN: ",  routing[idx].path.origin);
        if (parsedUrl.pathname === routing[idx].path.origin) {
            path = routing[idx].path;
            break;
        }
    }

    if (path){
        if (parsedUrl.search === null || parsedUrl.search === 'undefined') {
            parsedUrl.search = '';
        }
        handleRoute(parsedUrl.search, req, res, path);
        return;
    }
    returnError(req, res);
});
server.listen(NODE_PORT);
console.log('Server up on port: ',  NODE_PORT)

var proxy = httpProxy.createProxyServer({ignorePath: true});
proxy.on('proxyReq', function(proxyReq, req, res, options) {
    proxyReq.setHeader('X-Rundeck-Auth-Token', RUNDECK_APITOKEN);
    if(options.path.accept){
        proxyReq.setHeader('Accept', options.path.accept);
        proxyReq.setHeader('User-Agent', 'xpert/1.0');
    }

});

function handleRoute(search, req, res, path) {
    var url = req.url;
    proxy.web(req, res, {
        target: RUNDECK_SERVER + path.route + search,
        path: path
    });
}

function returnError(req, res) {
    res.writeHead(502, {'Content-Type': 'text/plain'});
    res.write('Bad Gateway for: ' + req.url);
    res.end();
}