Я пишу свой бэкэнд на Node / Express, и я ищу способ создать наследование ООП с моими контроллерами Express.
Моя структура выглядит так:
.
└── 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...
};
Я хотел бы, чтобы и putProject, и postProject расширили базовый класс, содержащий эту логику:
var data = JSON.parse(req.body.data);
req.files.forEach((item) => {
data[item.fieldname] = '/' + item.path;
});
Если у кого-то есть идея, как это можно написать, буду признателен!



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Идиоматический способ сделать это с помощью 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 для получения проанализированного содержимого, а не повторять код.
Затем вы можете использовать свой Маршрутизатор для более простой настройки общих промежуточных программ:
const projectRouter = express.Router();
projectRouter
.use(upload.any())
.use(parseProject)
.put('/:id', putProject)
.post('/:id', postProject);
app.use('/projects', projectRouter);
Вы также можете просто переместить этот проект, выполняющий синтаксический анализ, в его собственную функцию и заставить маршруты вызывать эту функцию.
Спасибо @Jacob, мне нравится ваш подход, но, как я уже сказал, есть задачи, которые нельзя обрабатывать в промежуточном программном обеспечении, см. multer req.body пусто. Так что мне все еще нужно использовать контроллеры.
Просто чтобы добавить что-то, что может быть очевидным для некоторых, если маршрутизатор также имеет такие методы, как
.get()и.delete(), ваше промежуточное программное обеспечение должно обрабатывать возможность отключенияreq.bodyили, может быть, просто проверьте значениеreq.method.