Last active
July 21, 2022 12:07
-
-
Save jeffwhelpley/5417758 to your computer and use it in GitHub Desktop.
Getting node.js http-proxy to play nice with restify. This will also work for http-proxy with express or another node.js server. Note that I took various snippets of my code for this gist in order to try and convey the general idea. It won't work to just run this file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
I have an existing node.js API server that runs on top of restify. I wanted to add http-proxy to forward | |
some calls to another API server. From the http-proxy examples out there, it seemed simply enough: | |
*/ | |
var httpProxy = require('http-proxy'); | |
var proxy = new httpProxy.RoutingProxy(); | |
var restify = require('restify'); | |
var server = restify.createServer(); | |
server.get('/foo/:bar', function(req, res) { | |
proxy.proxyRequest(req, res, { | |
host: 'somehost.com', | |
port: 80 | |
}); | |
}); | |
/* | |
But there is one pretty big reason why this didn't work for me. Later on in the code I have some restify middleware code: | |
*/ | |
server.use(restify.acceptParser(server.acceptable)); | |
server.use(restify.authorizationParser()); | |
server.use(restify.queryParser()); | |
server.use(restify.bodyParser({ mapParams: false })); | |
server.use(restify.gzipResponse()); | |
/* | |
The reason this causes a problem is that the middleware calls are modifying the request object | |
in a way that prevents the ability of http-proxy to forward the request. In order for the proxy | |
to work, we can't mess with the request too much. I still needed this middleware for my existing | |
non-proxy API calls, so I created the following wrapper to conditionally implement each middleware: | |
*/ | |
var wrapper = function(middleware) { | |
return function(req, res, next) { | |
var regex = /^\/foo.*$/; | |
// if url is a proxy request, don't do anything and move to next middleware | |
if(regex.test(req.url)) { | |
next(); | |
} | |
// else invoke middleware | |
else { | |
// some middleware is an array (ex. bodyParser) | |
if(middleware instanceof Array) { | |
middleware[0](req, res, function() { | |
middleware[1](req, res, next); | |
}); | |
} | |
else { | |
middleware(req, res, next); | |
} | |
} | |
}; | |
}; | |
// then I wrap my middleware calls with this function: | |
server.use(wrapper(restify.acceptParser(server.acceptable))); | |
server.use(wrapper(restify.authorizationParser())); | |
server.use(wrapper(restify.queryParser())); | |
server.use(wrapper(restify.bodyParser({ mapParams: false }))); | |
server.use(wrapper(restify.gzipResponse())); | |
/* | |
I will eventually make the wrapper function more generic and robust to handle other potential situations, | |
but I think you get the gist. | |
*/ |
Just introduced a proxy to a restify service and initially attempted this pattern but felt it was too intrusive.
We discovered server.pre()
from restify/pre which runs before all middleware and used it to setup a proxy.
Implemented this pattern and created a gist: https://gist.github.com/hartzis/ce191533d8579afe2481ddd5e2c6024a
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Webpack dev server now supports "proxy" parameter upon launch from javascript.
It works for me now.