Search code examples
javascriptnode.jsreverse-proxyhttp-proxynode-http-proxy

Single port route to different services


My question is: is http-proxy, reverse-proxy.js, or any other library(with exception of a web-server like nginx) capable of routing all requests that comes to the port 80 to another services based on the url?

If a request comes at the port 80 with that url localhost:80/route1 I want to redirect it to the service at localhost:3001

If a request comes at the port 80 with that url localhost:80/another-route I want to redirect it to the service at localhost:3002. And so on..

To summarize it: I want to expose 1 port(80), and then route the request to other services based on the URL pattern from the request. So far I tried this approach below using reverse-proxy.js but it only works if the port changes

{
  "port": 80,
  "routes": {
    "localhost/test": "localhost:3001",
    "localhost/another-route": "localhost:3002",
    "localhost/another-route-same-service": "localhost:3002",
    "*": 80
  }
}

Solution

  • Yes of course you can. It's a very common requirement. In Node you can do it natively using streams. Here's a full working example using only the standard Node http library.

    const http = require('http');
    const server = http.createServer();
    
    let routes = {
        '/test': {
            hostname: 'portquiz.net',
            port: 80
        }
    }
    
    function proxy(req, res){
        if (!routes[req.url]){
            res.statusCode = 404;
            res.end();
            return;
        }
    
        let options = {
            ...routes[req.url],
            path: '', // if you want to maintain the path use req.url
            method: req.method,
            headers: req.headers
        }
    
        let proxy = http.request(options, function(r){
            res.writeHead(r.statusCode, r.headers);
            r.pipe(res, { end: true });
        })
    
        req.pipe(proxy, { end: true }).on('error', err => console.log(err))
    }
    
    server.on('request', proxy);
    server.listen(8080);