简体   繁体   English

如何在 class 中制作 express 中间件?

[英]How do I make express middleware in class?

I currently use multer middleware like below我目前使用如下所示的 multer 中间件

const storage = multer.diskStorage({
  destination: function (req, file, cb) {
    cb(null, "public");
  },
  filename: function (req, file, cb) {
    cb(null, req.params.id + "_" + file.originalname);
  },
});


export const multerUploadSingle = (req: Request, res: Response, next: NextFunction) => {
  const upload = multer({ storage: storage }).single("file");

  upload(req, res, (error: unknown) => {
    if (error instanceof multer.MulterError) {
      const message = `file upload fail: ${error.message}`;
      next(new HttpException(message, HttpStatus.BadRequest));

    } else if (error instanceof Error) {
      const message = `file upload fail: ${error.message}`;
      next(new HttpException(message, HttpStatus.InternalServerError));

    } else {
      // upload success
      next();
    }
  });
}

and use in router like this并像这样在路由器中使用

FileRouter.post("/upload/:id", multerUploadSingle, (req, res) => {...});

However, I felt I want to refactor this middleware in class, and rewrote the code like this,但是,我感觉要重构class这个中间件,把代码重写成这样,

export class Multer {
  private readonly storage: multer.StorageEngine;

  constructor() {
    this.storage = multer.diskStorage({
      destination: function (req, file, cb) {
        cb(null, "public");
      },
      filename: function (req, file, cb) {
        cb(null, req.params.id + "_" + file.originalname);
      },
    });
  }

  uploadSingle(req: Request, res: Response, next: NextFunction) {
    const upload = multer({ storage: this.storage }).single("file");
  
    upload(req, res, (error: unknown) => {
      if (error instanceof multer.MulterError) {
        const message = `file upload fail: ${error.message}`;
        next(new HttpException(message, HttpStatus.BadRequest));
  
      } else if (error instanceof Error) {
        const message = `file upload fail: ${error.message}`;
        next(new HttpException(message, HttpStatus.InternalServerError));
  
      } else {
        // upload success
        next();
      }
    });
  }
}
const multer = new Multer();
FileRouter.post("/upload/:id", multer.uploadSingle, (req, res) => {...});

With my short knowledge, I think both case should have the same result, but the latter case which uses class made middleware doesn't work at all.以我的知识,我认为这两种情况应该有相同的结果,但后一种情况使用 class 制作的中间件根本不起作用。 It's seems method "uploadSingle" is never called, thus multer not uploading the file.似乎从未调用过“uploadSingle”方法,因此 multer 没有上传文件。

Did I make any mistake with class usage?我对 class 的用法有什么错误吗? or is it just express can only use function defined middleware?或者只是表示只能使用 function 定义的中间件?

Your code should follow the MVC pattern.您的代码应遵循 MVC 模式。 You can do stuff like this:你可以这样做:

routerFile.js路由文件.js

const upload = require("../../configs/multer");
const postController = require("../../controllers/postController");

const multiUploadEvent = upload.fields([
    { name: "images", maxCount: 2 },
    { name: "video", maxCount: 2 }
]);
router.post("/add-event-post", multiUploadEvent, postController.addEventPost);
module.exports = router;

multer.js multer.js

const multer = require('multer');

const multerFilter = (req, file, cb) => {
    console.log("Mime type :", file.mimetype.split('/')[0]);
    if (file.mimetype.split('/')[0] === 'image' || file.mimetype.split('/')[0] === 'video' || file.mimetype.split('/')[0] === 'audio') {
        cb(null, true);
    } else {
        cb(new Error('Please upload img, audio, or video file only.'), false);
    }
};
const storage = multer.memoryStorage();
const upload = multer({
    storage: storage,
    fileFilter: multerFilter,
    limits: {
        fileSize: , 50 * 1024 * 1024// 50 Mb
    },
});
module.exports = upload;

postController.js postController.js

const addEventPost = async (request, response) => {
    try {
        let { title, ..... } = request.body;
        const images = request.files.images;
        const video = request.files.video;

        
        console.log(title);
        console.log(images);
        console.log(videos);
        //upload to services likes aws and save to database
        .
        .
        .
        return response
           .status(200)
           .json({
                  message: "Event post added successfully"
            });

} catch (error) {
    console.log(error);
    response.status(500).json({
        error: "Something went wrong",
    });
}

} }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM