【问题标题】:OOP Inheritance in Express routerExpress 路由器中的 OOP 继承
【发布时间】:2019-02-19 16:25:48
【问题描述】:

我正在使用 Node/Express 编写后端,并且正在寻找一种方法来使用我的 Express 控制器创建一些 OOP 继承。

我的结构如下:

.
└── server
    ├── App.js
    ├── controllers
    │   ├── articles.js
    │   └── project.js
    ├── models
    │   ├── articles.js
    │   ├── projects.js
    ├── routes
    │   ├── articles.js
    │   ├── projects.js
    └── views
        ├── error.ejs
        ├── index.ejs
        └── layout.ejs

有些控制器共有的一些任务无法由中间件处理。为此,我想创建一个基本的controller 类,其中包含将由所有控制器实例共享的一些功能。

想象一下我有这样的路线:

// routes/project.js

router.put('/:id', upload.any(), putProject);    
router.post('/:id', upload.any(), postProject);

还有控制器:

// controllers/project.js

export const putProject = function(req, res, next) {
    var data = JSON.parse(req.body.data);
    // Retrieving files appended by Multer to req.files
    req.files.forEach((item) => {
        data[item.fieldname] = '/' + item.path;
    });

    models.Projects.update(data, {
        include: [{ model: models.ProjectImages }],
        returning: true,
        plain: true,
        where: {
            id: req.params.id,
        },
    });
    // etc...
};

export const postProject = function(req, res, next) {
    // Retrieving files appended by Multer to req.files
    var data = JSON.parse(req.body.data);
    req.files.forEach((item) => {
        data[item.fieldname] = '/' + item.path;
    });
    models.Projects.create({
        title: req.body.title,
        description: req.body.description,
        ArticleId: req.body.ArticleId,
    })
    // etc...
};

我希望 putProjectpostProject 都扩展一个包含此逻辑的基类:

var data = JSON.parse(req.body.data);
req.files.forEach((item) => {
    data[item.fieldname] = '/' + item.path;
});

如果有人知道如何写,我将不胜感激!

【问题讨论】:

    标签: javascript node.js oop express


    【解决方案1】:

    使用 Express 执行此操作的惯用方法是使用中间件作为公共位,并在您的路由中重用该中间件。例如,这个中间件可以负责解析项目数据:

    function parseProject(req, res, next) {
      res.locals.project = JSON.parse(req.body.data);
      req.files.forEach((item) => {
        res.locals.project[item.fieldname] = '/' + item.path;
      })
      next();
    }
    

    ...允许每个路由处理程序访问res.locals.project 以获取解析后的内容,而不是重复代码。

    然后你可以使用你的Router 更容易地配置常用中间件:

    const projectRouter = express.Router();
    projectRouter
      .use(upload.any())
      .use(parseProject)
      .put('/:id', putProject)
      .post('/:id', postProject);
    
    app.use('/projects', projectRouter);
    

    您也可以将该项目解析通用性移至其自己的函数并让路由调用该函数。

    【讨论】:

    • 只是添加一些对某些人来说可能很明显的东西,如果路由器也有像 .get().delete() 这样的方法,你的中间件应该处理 req.body 未设置的可能性,或者只是检查req.method的值
    • 谢谢@Jacob,我喜欢你的方法,但正如我所说,有些任务无法在中间件中处理,请参阅multer req.body empty。所以我仍然需要使用控制器。
    猜你喜欢
    • 1970-01-01
    • 2013-02-11
    • 1970-01-01
    • 2016-06-25
    • 2018-05-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多