Samo
Samo

Reputation: 8240

How to set up http-proxy-middleware on a dynamic route?

I'm trying to proxy some asset routes where a dynamic part of the path comes from a config file. I had this working using the request library, but I can't quite get it working with http-proxy-middleware.

Here's the code that works when I use the request library:

  const assets = express.Router();
  app.use(`/${p.name}/assets`, assets);
  assets.get('*', async (req, res) => {
    return request(`${p.address}/${p.version}/assets${req.path}`).pipe(res);
  });

I've tried a few different variations with http-proxy-middleware, and none of these work. Example 1:

  app.use(
    `/${p.name}/assets`,
    httpProxy({
      target: `${p.address}`,
      changeOrigin: true,
      pathRewrite: {
        [`^${p.name}`]: `${p.version}`,
      },
    })
  );

Example 2:

  app.use(
    `/${p.name}/assets`,
    httpProxy({
      target: `${p.address}`,
      changeOrigin: true,
      pathRewrite: function(path) {
        return path.replace(p.name, p.version);
      }
    })
  );

I've also tried using /${p.name}/assets/** as the first argument to app.use, and I've also tried adding a /assets to the end of both the key and value in the pathRewrite object. The result is always the same: I get a 302 for the asset requested by the browser.

I've even tried adding a middleware function right before the httpProxy call that logs to the console so that I know my request is hitting the correct route:

  app.use(
    `/${p.name}/assets`,
    (req, _res, next) => {
      console.log("I'm an asset proxy, short and stout: ", req.url);
      next();
    },
    httpProxy({
      target: `${p.address}`,
      changeOrigin: true,
      pathRewrite: {
        [`^${p.name}`]: `${p.version}`,
      },
    })
  );

But I don't ever see that output. Probably a simple mistake. Perhaps my first argument to app.use just isn't right? Help appreciated!

Update

I also tried a combination of the old way and the new. I mounted a new router on /${p.name}/assets, and after discovering the onProxyRequest option, I added a function there to log some output.

  const assets = express.Router();
  app.use(`/${p.name}/assets`, assets);
  assets.use(
    '*',
    httpProxy({
      target: p.address,
      changeOrigin: true,
      pathRewrite: {
        [`^${p.name}`]: p.version,
      },
      onProxyReq: (proxyReq, req, res) => {
        console.log("Hello I'm being proxied now! ", proxyReq, req, res);
      },
    })
  );

Still getting a 302, and I never see the output from the onProxyReq function.

Upvotes: 5

Views: 5492

Answers (2)

Yilmaz
Yilmaz

Reputation: 49265

Documentation has custom router option.

-

const proxyTable = {
  'integration.localhost:3000': 'http://localhost:8001', // host only
  'staging.localhost:3000': 'http://localhost:8002', // host only
  'localhost:3000/api': 'http://localhost:8003', // host + path
  '/rest': 'http://localhost:8004', // path only
};

const options = {
  target: 'http://localhost:8000',
  router: proxyTable,
};

const myProxy = createProxyMiddleware(options);
  • or
function customRouter(req) {
  // I dont know what "p" stands for 
  // check the req object to see which property you want to modify
  console.log(req)
  const { hostname } = req
  const hostName = hostname.split('.')[0]
  return `https://${hostName}.sub.domain.com`
}

then add this option:

  router: customRouter

Upvotes: 1

jeeves
jeeves

Reputation: 2031

Can you check your installed version - looks like you are using the v0.x.x. interface to the http-proxy-middleware package. Latest is version 2.X.X and it exposes the following function

const { createProxyMiddleware } = require('http-proxy-middleware');

app.use(
  `/${p.name}/assets`,
  createProxyMiddleware({
    target: `${p.address}`,
    changeOrigin: true,
    pathRewrite: {
      [`^${p.name}`]: `${p.version}`,
    },
  })
);

Upvotes: 0

Related Questions