Добрый вечер, одна из главных проблем моих проектов - повторения и шаблонный код, что нарушает DRY, я стремлюсь к максимальной декомпозиции, но на мой взгляд часто это избыточно и усложняет проект.
Например есть middleware Multer (загрузка файлов):
// categoryRouter.js
const fileFilter = (req, file, cb) => {
const allowedMimeType = ['image/png', 'image/jpeg', 'image/jpg'];
if (allowedMimeType.includes(file.mimetype) {
cb(null, true);
} else {
cb(new Error('Invalid file type'));
}
};
const storage = multer.diskStorage({
destination: (req, file, cb) => {
cb(null, path.resolve('public/uploads/categories'));
},
filename: (req, file, cb) => {
cb(null, `${uuidv4()}${path.extname(file.originalname)}`);
}
});
router.post('/:slug/uploadImage', multer({ storage, fileFilter }).single('image'), (req, res) => {
// сохранить путь в бд
});
Этот кусок повторяется из модуля в модуль, меняется лишь destination (путь) сохранения и fileFilter (валидатор файла), мне кажется логично декомпозировать этот код примерно так:
fileHelper.js
Проверка на MimeType, генерация уникального имени файла уходят в отдельный модуль-хелпер
// fileHelper.js
exports.isImage = ({ mimetype }) => ['image/png', 'image/jpeg', 'image/jpg'].includes(mimetype);
exports.getUniqueFileName = (originalName) => `${uuidv4()}${path.extname(originalName)}`;
fileFilter
fileFilter уходит в отдельный модуль - utils
// fileFilter.js
module.exports = (fileValidation) => {
return (req, file, cb) => {
if (fileValidation(file)) {
cb(null, true);
} else {
cb(new Error('Invalid file type'));
}
};
};
Фабрика multer (uploadImage)
storage не вижу смысла выносить отдельно-
module.exports = (destination) => {
const filter = fileFilter(fileHelper.isImage);
const storage = multer.diskStorage({
destination: (req, file, cb) => {
cb(null, destination);
},
filename: (req, file, cb) => {
cb(null, fileHelper.getUniqueFileName(file.originalname));
}
});
return multer({ storage, fileFilter });
};
И в итоге вместо копирование, у нас есть "генератор" middleware:
const uploadImage = require('./multerFactory')('public/uploads/category');
router.post('/:slug/uploadImage', uploadImage.single('image'), (req, res) => {
// сохранить ссылку на файл в бд
});
1. На сколько такой подход оправдан и необходим?
2. Как обычно поступают в подобных случаях?
3. Не избыточно ли я декомпозировал все? (либо можно еще лучше, как?)
P.S. Не могу найти "боевой", реальный пример полноценного приложения на express / node, отсюда куча "философских" вопросов на который сложно найти однозначный ответ.