Express Router:转换为ObjectId错误

时间:2017-11-22 10:56:01

标签: javascript node.js express mongoose

我在调用t时遇到以下错误 users/status 路线

{
"message": "Cast to ObjectId failed for value \"status\" at path \"_id\" for model \"Users\"",
"name": "CastError",
"stringValue": "\"status\"",
"kind": "ObjectId",
"value": "status",
"path": "_id"
}

我正在使用find() mongoose方法来获取符合条件的所有文档。现在find()不会_idfindById的方式类似。

奇怪的是我能解决的唯一方法是移动我的Express Router定义。 (见下文)

这种方法不起作用:

// users
router
 .route('/users')
 .get(getAll)
 .post(createNew);

router
 .route('/users/:id')
 .put(updateExisting)
 .get(getOne)
 .post(upload.single('proposal'), uploadFile); 

router
 .route('/users/status')
 .get(status);

这种方式有效:(请注意users/statususers/:id的交换方式

// users
router
 .route('/users')
 .get(getAll)
 .post(createNew);

router
 .route('/users/status')
 .get(status);

router
 .route('/users/:id')
 .put(updateExisting)
 .get(getOne)
 .post(upload.single('proposal'), uploadFile);

users/status的控制器:

let status = (req,res) => {

  User.find({usersProposals: {$exists: true, $not: {$size: 0}}})
     .exec()
     .then((data) => {sendJsonResponse(res, 200, data)})
     .catch(err => {sendJsonResponse(res, 500, err)})

 };

仅供参考:我正在运行mongoose v4.13.4并表达v4.15.5

我不确定我做错了什么。好像我在某个地方犯了一个愚蠢的错误。

2 个答案:

答案 0 :(得分:2)

第二种路由技术是正确的。

第一个路由排序的问题是您的.route('/users/:id')在路由.route('/users/status')之前匹配,因为网址路径/users/status满足路由/users/:id。 实际上,如果您在/user/路径之后传递任何内容,例如,/users/anythingHere将与/users/:id路径匹配。

这是Express.js的工作方式。您定义的路由按照定义的顺序依次匹配。因此,您的第二个路由设置是正确的。

答案 1 :(得分:1)

这是解释REST API设计的答案,Joytman Singh的答案是正确的,因此我没有详细说明。

您遇到的问题基本上告诉您REST设计不正确。两个控制器不应该提供URL,并且顺序无关紧要(对于某些预处理程序,后处理程序很重要,但在具有相同重要性和类似服务的控制器之间无关紧要。)

例如,如果两个控制器能够捕获相同的URL,则第一个捕获它,发送响应并通常结束链。有可能你甚至没有注意到它。当你删除第一个时会发生什么?好吧,您希望在该URL上获得404,而不是这样,它将开始执行不同的代码。你不想要这个。

标准REST API设计基本上是这样的:/collection/id/collection/id...,在现实世界中你可以拥有/users/34/images

如果您想要列表,请停在收藏集/users/34/images,如果您需要详细信息,请停在ID /users/34

如果你需要像&#34这样的过滤器,那么只找到存在的用户"你应该用查询字符串/users?exist=true来做。然后在你的控制器中基于这些选项(使用if (req.query.exist='true')),你可以做不同的事情,但应该有一个控制器来处理它。

如果您需要一些非常特殊的东西,即连接到用户,但它不返回用户对象,最好创建完全不同的URL,如/statuses/users(其中用户是" id& #34;状态)或/statuses?users=1

之类的东西