Search code examples
node.jsmodel-view-controllercontrolleruploadmulter

Multer upload should not be in the routes file


The only way I can make Multer upload files is putting the multer logic in routes.js, but it doesn't seem right, since I'm using MVC.

The controller.js:

const upload_post = async (req, res, next) => { res.send('file uploaded') }

The routes.js:

router.post('/send', upload.single('image'), controller.upload_post)

The problem is, I have to put all Multer logic in routes.js file (upload, destination, storage, etc), otherwise it won't recognize the middleware upload.single. It works, but doesn't seem to be the best approach. So, is there a way to improve this code?


Solution

  • You can still keep all Multer upload logic inside your controller. Take a look at the Express Multer Error Handling section (at the bottom). It allows you to call the upload middleware programatically within other middleware, so you don't need to define it in your top route handler.

    For example you would use this:

    index.js

    const express = require("express");
    const multer = require("multer");
    const bodyParser = require("body-parser");
    const app = express();
    
    const upload = multer().single("inputFile");
    
    app.use(bodyParser.text({ type: "text/plain" }));
    
    const OtherMiddleware = (req, res) => {
      upload(req, res, function (err) {
        if (!req.file) {
          res.error({ status: 500, message: "foo", detail: "bar" });
        } else if (err instanceof multer.MulterError) {
          console.log(err);
          // res.error({ status: 500, message: "multer", detail: "err" });
          // A Multer error occurred when uploading.
        } else if (err) {
          console.log(err);
          // An unknown error occurred when uploading.
        }
        // Everything went fine.
        console.log("File Uploaded", req.file.originalname);
        // send the file back to the server for example
        res.send(req.file.buffer);
      });
    };
    
    app.get("/", (req, res) => {
      res.json({ visit: "/upload" });
    });
    
    app.post("/upload", OtherMiddleware);
    
    app.listen(3000, () => {
      console.log("Multer Upload API is listening on port 3000");
    });
    

    Here's a working sandbox I created to demonstrate this functionality.