对不同数据类型的相同操作重复代码,Express(nodejs) app with mongoose
Repeating code for same operation of different datatypes, Express(nodejs) app with mongoose
我正在创建一个 Express rest API,它连接到 MongoDB with mongoose。该数据库有几种不同的数据类型:User
、Book
、Food
等。当我为这些数据类型编写端点和函数时。我意识到我重复了很多相同的代码,例如下面的代码:
// Book.js
import Book from './models/Book'
function deleteById (req, res, next) {
Book.findByIdAndRemove(req.params.id, function (err) {
if (err) {
let error = new Error('Failed to delete an book in database')
error.statusCode = 500
return next(error)
}
res.json({
success: true,
message: 'Book deleted successfully'
})
})
}
我可以将 Book
更改为 User
或 Food
,并且可以使用相同的代码。这会导致大量重复代码,如下所示:
// Food.js
import Food from './models/Food'
function deleteById (req, res, next) {
Food.findByIdAndRemove(req.params.id, function (err) {
if (err) {
let error = new Error('Failed to delete an food in database')
error.statusCode = 500
return next(error)
}
res.json({
success: true,
message: 'Food deleted successfully'
})
})
}
所以我想知道是否有一种方法可以生成函数,这样我就不需要为每种类型的数据重复 deleteById
函数的代码。最佳做法是什么?还是尝试生成函数并且需要重复是一种不好的做法?
非常感谢任何帮助,在此先感谢。
您可以创建删除中间件。在下面的代码中,我将模型 delete function
作为 argument
传递,而我 return 是一个中间件。在那个中间件函数中,我调用动态出现的删除 function
。
var deleteMiddleWare = function(deleteByIdFunc, name) {
var deleteId = req.params.id;
if (!deleteId)
res.json({
success: false,
message: `Please provide ${name} id.`
})
return function(req, res, next) {
deleteByIdFunc(req.params.id, function(err) {
if (err) {
let error = new Error(`Failed to delete ${name} in database`)
error.statusCode = 500
return next(error)
}
res.json({
success: true,
message: `${name} deleted successfully`
})
})
}
}
router.get(/user/delete /: id, deleteMiddleWare(User.deleteById, 'User'))
router.get(/food/delete /: id, deleteMiddleWare(Food.deleteById, 'Food'))
经过大量研究,我发现最好的方法是使用 class 构造函数并将数据类型作为变量传递:
class BaseController {
constructor (type, name) {
if (!type || !access) {
throw new Error('Must define datatype')
}
this.datatype = type
this.name = name
this.deleteById = this.deleteById.bind(this)
}
deleteById (req, res, next) {
let name = this.name
this.datatype.findByIdAndRemove(id, function (err) {
if (err) {
let error = new Error(`Failed to delete ${name} in database`)
error.statusCode = 500
return next(error)
}
res.json({
success: true,
message: `${name} deleted successfully`
})
})
}
}
在路由器文件中,我们可以直接调用
const food = new BaseController(Food, 'Food')
router.get('/food/delete/:id', food.deleteById)
我正在创建一个 Express rest API,它连接到 MongoDB with mongoose。该数据库有几种不同的数据类型:User
、Book
、Food
等。当我为这些数据类型编写端点和函数时。我意识到我重复了很多相同的代码,例如下面的代码:
// Book.js
import Book from './models/Book'
function deleteById (req, res, next) {
Book.findByIdAndRemove(req.params.id, function (err) {
if (err) {
let error = new Error('Failed to delete an book in database')
error.statusCode = 500
return next(error)
}
res.json({
success: true,
message: 'Book deleted successfully'
})
})
}
我可以将 Book
更改为 User
或 Food
,并且可以使用相同的代码。这会导致大量重复代码,如下所示:
// Food.js
import Food from './models/Food'
function deleteById (req, res, next) {
Food.findByIdAndRemove(req.params.id, function (err) {
if (err) {
let error = new Error('Failed to delete an food in database')
error.statusCode = 500
return next(error)
}
res.json({
success: true,
message: 'Food deleted successfully'
})
})
}
所以我想知道是否有一种方法可以生成函数,这样我就不需要为每种类型的数据重复 deleteById
函数的代码。最佳做法是什么?还是尝试生成函数并且需要重复是一种不好的做法?
非常感谢任何帮助,在此先感谢。
您可以创建删除中间件。在下面的代码中,我将模型 delete function
作为 argument
传递,而我 return 是一个中间件。在那个中间件函数中,我调用动态出现的删除 function
。
var deleteMiddleWare = function(deleteByIdFunc, name) {
var deleteId = req.params.id;
if (!deleteId)
res.json({
success: false,
message: `Please provide ${name} id.`
})
return function(req, res, next) {
deleteByIdFunc(req.params.id, function(err) {
if (err) {
let error = new Error(`Failed to delete ${name} in database`)
error.statusCode = 500
return next(error)
}
res.json({
success: true,
message: `${name} deleted successfully`
})
})
}
}
router.get(/user/delete /: id, deleteMiddleWare(User.deleteById, 'User'))
router.get(/food/delete /: id, deleteMiddleWare(Food.deleteById, 'Food'))
经过大量研究,我发现最好的方法是使用 class 构造函数并将数据类型作为变量传递:
class BaseController {
constructor (type, name) {
if (!type || !access) {
throw new Error('Must define datatype')
}
this.datatype = type
this.name = name
this.deleteById = this.deleteById.bind(this)
}
deleteById (req, res, next) {
let name = this.name
this.datatype.findByIdAndRemove(id, function (err) {
if (err) {
let error = new Error(`Failed to delete ${name} in database`)
error.statusCode = 500
return next(error)
}
res.json({
success: true,
message: `${name} deleted successfully`
})
})
}
}
在路由器文件中,我们可以直接调用
const food = new BaseController(Food, 'Food')
router.get('/food/delete/:id', food.deleteById)