4

I need what is essentially a reverse proxy but I need it in Node.js as I will have to put in some custom functionality.

The gateway will be the only visible service, and it needs to forward traffic on to an internal network of services. A simple 302 isn't going to work here.

How can I realistically achieve this with Node.js given the asynchronous nature of it?

Are there any well known libraries used for this?

enter image description here

3 Answers 3

3

I've managed this using node-http-proxy, where http://first.test/ and http://second.test/ are the hostnames.

var http = require('http'),
    httpProxy = require('http-proxy');

var proxy = httpProxy.createProxyServer({});

// reverse proxy server
http.createServer(function (req, res) {
    var target = '';

    if (req.headers.host.match(/first.test/)) {
        target = 'http://127.0.0.1:8001';
    } else if (req.headers.host.match(/second.test/)) {
        target = 'http://127.0.0.1:8002';
    }

    console.log(req.headers.host, '->', target);
    proxy.web(req, res, { target: target });
}).listen(8000);

// test server 1
http.createServer(function(req, res) {
    res.writeHead(200, { 'Content-Type': 'text/plain' });
    res.write('8001\n');
    res.write(JSON.stringify(req.headers, true, 2));
    res.end();
}).listen(8001);

// test server 2
http.createServer(function(req, res) {
    res.writeHead(200, { 'Content-Type': 'text/plain' });
    res.write('8002\n');
    res.write(JSON.stringify(req.headers, true, 2));
    res.end();
}).listen(8002);
Sign up to request clarification or add additional context in comments.

Comments

2

For a simple reverse proxy that uses the reactor pattern (like node), I would check out nginx. But, you mentioned you wanted to add in some custom functionality using node, so is that a realistic goal? Absolutely! Here are some things to think about when you are designing your reverse proxy:

  • How will you keep track of where incoming requests need to end up? For example, if you proxy all request with /test/* to your UI, but the returned HTML has root relative URLs (/imgs/banner.jpg), how do you keep track of where the subsequent request needs to go (especially if it comes from javascript)? Are you going to tightly couple your proxy and your back end applications? Or you might consider setting a cookie to keep track.
  • Does this thing need to scale at all? If your answer is no, my follow up is - are you sure? If you really just need to proxy to two backend applications, I'm sure there are any number of clever ways to achieve that. If at any time you may have N back end applications, then you need a solid plan for managing (add/remove/update) them on the proxy.
  • Do your applications use HTTPS? If so, are you going to terminate SSL on the proxy? Can you send data in the clear between your proxy and your back end applications?

Good luck on your reverse proxy endeavors! I will update this if anything else occurs to me.

1 Comment

Some very good points. All routing will be hostname, not path, based. Scaling will be involved, but that is another question. SSL will also be used but again, this is a question for another part of the design. You do raise some good points though, and I thank you for having a deep think about them!
1

With pure core module (may be a bit ugly, but efficient):

var http = require('http');

http.createServer(function (request, response) {
    if (request.headers.host === 'api.test') {
        // request data from 172.17.0.1:80
    } else if (request.headers.host === 'test') {
        // request data from 172.17.0.2:80
    } else {
        // Do something else
    }
}).listen(80);

If you don't like this example, you can try: https://www.npmjs.org/package/turtle.io

2 Comments

Thanks, not heard about turtle.io. I managed to get this working using node-http-proxy (below). Thanks for your response though, definitely got the same logic as me, just popped in the proxyServer and that's everything I need. Thanks for your input!
A lookup table would be way better for this: { "api.test" : function() { ... }, ...} could be used as a simple dispatch table.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.