req.file undefined when express.json() is used in gateway service

Viewed 118

I have 3 services:

  1. A React app
  2. A Node express gateway
  3. A Node express backend

I send files from the React app to the backend using a proxy in the gateway. The thing is if express.json() or express.urlencoded() middlewares are set before the proxy the req.file is empty after multer encoded it.

Relevant code:

react app:

const formData = new FormData();

formData.append("file", file);
formData.append("type", "pdf");
formData.append("contentId", "srfewrgferg");

console.log(formData.get("file"));

axios.post( config.BASE_URL + "/activities/create", formData)

gateway:

const router = express();

router.use(express.json());
router.use(express.urlencoded({ extended: true }));

router.post("/activities/*", proxy( `${config.urlPresupuestos}/`, { 
  proxyReqPathResolver: ( req: Request ) => {
    return req.originalUrl;
  }
}));

backend:

const router = express();

router.use(multerMiddleware.single("file"));

router.post("/activities/create", (req, res) => {
  console.log(req.file)
});

If I remove the express middlewares in the gateway all works fine, but I need those middlewares for other routes. Any suggestion why this could be happening?

1 Answers

I assume you are using express-http-proxy for your proxy.

Whether it's a bug or an intentional design, it seems that including body parsing middleware before the proxy will break POST requests.

I don't claim to know why this breaks the proxy, but you can generally work around these kinds of problems by simply re-ordering your routes such that the proxy routes are defined before your middleware:

const router = express();

// Proxy routes go here
router.post("/activities/*", proxy( `${config.urlPresupuestos}/`, { 
  proxyReqPathResolver: ( req: Request ) => {
    return req.originalUrl;
  }
}));

// Now install the middleware required by other routes
router.use(express.json());
router.use(express.urlencoded({ extended: true }));

// Other routes...
router.use(/*...*/);

Express middleware is run in the order it is installed, so even though you've installed these middleware functions at the root of your router, they won't be invoked in the event the proxy route matches and is invoked.

Related