我正在使用Express& amp;设置我的第一个RESTful API Mongo DB。到目前为止,我一直试图想出一个模式,如果我暂时不在项目上工作,我可以轻松地重新开始,如果有新人加入该项目,也会如此。
基本思路是当有人点击端点时,如果该端点需要修改一个或多个Mongo DB文档,那么我将继续在Mongo DB中获取该文档并将其存储在res.locals中以进行操作后来在另一个中间件中。这显示在exports.populateUserById:
中No1 = card.loc[card['insert'] == 'Standard', 'dollars']
#original solution
#No1 = card.dollars[card['insert'] =='Standard']
然后,我将在一个单独的中间件中修改Mongo DB文档,并引用上一个中间件中的res.locals,我可以调用exports.populateUserById = async (req,res,next) => {
const user = await User.findById(req.body.userId);
res.locals.userToAction = user;
next();
}
没问题。:
.save()
最后,我转到我的最后一个中间件,该中间件由刚刚发送res.JSON的所有端点共享:
exports.addToTeam = async (req, res, next) => {
res.locals.userToAction.team = req.body.teamId;
await res.locals.userToAction.save();
res.locals.responseData = { success: true }
next();
}
我的完整终点在我的路线中看起来像这样:
exports.respond = (req,res) => {
res.json(res.locals.responseData);
}
我发现这个方法很方便,因为我可以在许多不同的端点上调用populateUserById控制器函数,然后在另一个控制器函数中编辑文档我需要的方法。
对于使用Mongo DB / Express的RESTful API,这是一个相当典型/可接受的模式,还是我走错了路?
另外值得一提。显然,在它们之间有更多的控制器函数来检查有效的MongoDB对象id并捕获异步错误,但是已经将它们排除在这个例子之外。
谢谢!
答案 0 :(得分:3)
你的确是我认为不好的做法。
exports.populateUserById = async (req,res,next) => { const user = await User.findById(req.body.userId); // ... }
我发现这种方法很方便,因为我可以打电话给 populateUserById控制器函数然后在许多不同的端点上 在另一个控制器功能中编辑文档我需要的方式。
如果您想在某天仅更改1条路线的请求正文参数的名称,该怎么办?您是否打算为此创建另一个中间件?
ExpressJs中间件用于划分不同的用例,而不是代码行。
E.g。
router.get('/foo',
(req, res, next) => {
if (!isAdmin) next();
// Admin logic
},
(req, res, next) => {
// User logic
}
);
我可以看到你也使用了Mongoose。那么,为什么不在模型中创建方法或静态函数以便以后重用呢?
const userSchema = new mongoose.Schema({
team: {type: String}
});
userSchema.methods = {
async addTeam(team) {
this.team = team;
await this.save();
}
}
const User = mongoose.model('User', userSchema);
// ...
router.post('/user/:userId/team', async (req, res, next) {
const user = User.findById(req.params.userId);
await user.addTeam(req.body.teamId);
res.status(200).json(user);
});
它具有相同数量的代码行。它更容易测试,维护和扩展。
答案 1 :(得分:1)
您可以通过路径名中的小改变
以相同的方式调用这些函数router.post('/add/user/team',
authController.populateUserById,
authController.addToTeam,
authController.respond
);
但是你也可以按照快速路线中间件方法,你需要在路线本身传递userId和teamId
router.post('/user/:userId/:teamId',authController.respond);
router.param('userId', authController.populateUserById);
router.param('teamId', authController.addToTeam);
您将在req.params中获得 userId,teamId 。
或
如果您想将userId和teamId保留在正文中。你也可以这样做。虽然我更喜欢以前的方法。
router.post('/add/:user/:team/',authController.respond);
router.param('user', authController.populateUserById);
router.param('team', authController.addToTeam);