0

I am basically following the code in here.

I generate my Express project using npx express-generator

In my routes/index.js I do this

var express = require("express");
var router = express.Router();
const {
  createProxyMiddleware
} = require("http-proxy-middleware");

/**
 * Configure proxy middleware
 */
const jsonPlaceholderProxy = createProxyMiddleware({
  target: "http://jsonplaceholder.typicode.com/users",
  changeOrigin: true, // for vhosted sites, changes host header to match to target's host
  logger: console,
});

router.use('/test', jsonPlaceholderProxy);

module.exports = router;

In my app.js I just redirect all / request to my routes/index.js by doing this

var createError = require("http-errors");
var express = require("express");
var path = require("path");
var cookieParser = require("cookie-parser");
var logger = require("morgan");

var indexRouter = require("./routes/index");

var app = express();

// view engine setup
app.set("views", path.join(__dirname, "views"));
app.set("view engine", "ejs");

app.use(logger("dev"));
app.use(express.json());
app.use(express.urlencoded({
  extended: false
}));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, "public")));

app.use("/", indexRouter);  

// catch 404 and forward to error handler
app.use(function(req, res, next) {
  next(createError(404));
});

// error handler
app.use(function(err, req, res, next) {
  // set locals, only providing error in development
  res.locals.message = err.message;
  res.locals.error = req.app.get("env") === "development" ? err : {};

  // render the error page
  res.status(err.status || 500);
  res.render("error");
});

module.exports = app;

I start the app by running npm start

I can see

npm start

[email protected] start
node ./bin/www  

[HPM] Proxy created: /  -> http://jsonplaceholder.typicode.com/users

So far so good. My app is running on http://localhost:3000

Now I use Postman to hit http://localhost:3000/test (GET)

I get http status code 504 Gateway Timeout with message [HPM] Error occurred while proxying request localhost:3000/test to http://jsonplaceholder.typicode.com/

Meanwhile, if I hit http://jsonplaceholder.typicode.com/users (GET) directly using Postman, I get status 200 and a very long JSON body as the response , indicating that the API is live and running OK.

I am wondering, what have I done wrongly?


Update with the solution

I fix the issue by

  1. Adding pathRewrite as suggested by @Mahesh
  2. Remove all the middlewares added automatically by express-generator

For this simple scenario, I don't need those middlewares. But definitely there are some scenarios that may need those middlewares. Not sure how to solve the issue when we do need those middlewares.

So, the routes/index.js looks like this

var express = require("express");
var router = express.Router();
const {
  createProxyMiddleware
} = require("http-proxy-middleware");

/**
 * Configure proxy middleware
 */
const jsonPlaceholderProxy = createProxyMiddleware({
  target: "http://jsonplaceholder.typicode.com/users/",
  changeOrigin: true, // for vhosted sites, changes host header to match to target's host
  logger: console,
  pathRewrite: {
    // Rewrite the request path to remove the `/test` prefix
    "^/test": "",
  },
});

router.use("/test", jsonPlaceholderProxy);

module.exports = router;

And my app.js looks like this

var createError = require("http-errors");
var express = require("express");
var path = require("path");
var cookieParser = require("cookie-parser");
var logger = require("morgan");
var bodyParser = require('body-parser')

var indexRouter = require("./routes/index");

var app = express();

// view engine setup
app.set("views", path.join(__dirname, "views"));
app.set("view engine", "ejs");


//Remove all these parsers added automatically by express-generator
//Activating these line below would make the proxy fails. Not sure why?
/*
app.use(logger("dev"));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, "public")));
app.use(bodyParser.json());
app.use(bodyParser.raw());
app.use(bodyParser.text());
*/

app.use("/", indexRouter);

// catch 404 and forward to error handler
app.use(function(req, res, next) {
  next(createError(404));
});

// error handler
app.use(function(err, req, res, next) {
  // set locals, only providing error in development
  res.locals.message = err.message;
  res.locals.error = req.app.get("env") === "development" ? err : {};

  // render the error page
  res.status(err.status || 500);
  res.render("error");
});

module.exports = app;

Re-run the app, and hit http://localhost:3000/test again using Postman. Now it works.

1 Answer 1

2

I think this will fix your issue

 const jsonPlaceholderProxy = createProxyMiddleware({
  target: "http://jsonplaceholder.typicode.com/users",
  changeOrigin: true, // for vhosted sites, changes host header to match to target's host
  logger: console,
  pathRewrite: {
    // Rewrite the request path to remove the `/test` prefix
    "^/test": "",
  },
})

The issue with the original code was that the /test prefix was included in the request path when the proxy middleware was used. This caused the requests to be sent to the wrong URL.

Sign up to request clarification or add additional context in comments.

3 Comments

I added the pathRewrite thing and re-run the app. I still get [HPM] Proxy created: / -> http://jsonplaceholder.typicode.com/users [HPM] Proxy rewrite rule created: "^/test" ~> "" [HPM] Error occurred while proxying request localhost:3000 to http://jsonplaceholder.typicode.com/users [ECONNRESET] (https://nodejs.org/api/errors.html#errors_common_system_errors) GET /test 504 15116.966 ms - -
you are right. That pathRewrite is one of the issues. Just curious, if I did not add pathRewrite thing, would the target URL become jsonplaceholder.typicode.com/users/test ?
Not sure but I think it was replacing /users with /test. You can log inside the request and check console.log(req.url).

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.