我在调用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()
不会_id
与findById
的方式类似。
奇怪的是我能解决的唯一方法是移动我的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/status
和users/: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
我不确定我做错了什么。好像我在某个地方犯了一个愚蠢的错误。
答案 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