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
project@0.0.0 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?
I fix the issue by
pathRewrite
as suggested by @Maheshexpress-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.
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.