Node JS / Mongo DB - 最佳实践restful API

时间:2018-03-27 13:35:46

标签: javascript node.js mongodb express

我正在使用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并捕获异步错误,但是已经将它们排除在这个例子之外。

谢谢!

2 个答案:

答案 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);