用户自我关注限制失效问题排查及HTTP请求方法选型咨询
问题解决:自我关注限制失效与HTTP方法选择
一、自我关注判断失效的修复
你的判断逻辑if(userToModify === currentUser)不生效,核心原因是Mongoose查询返回的是独立的文档对象,即使是同一个用户,两个对象的内存引用不同,全等比较会返回false。
修复步骤
- 调整判断顺序:先检查用户是否存在,再判断是否为自身(避免用户不存在时的无效判断)
- 比较用户的
_id值(统一转为字符串,避免ObjectId与字符串的类型差异)
修改后的完整代码:
const followUnfollowUser = async(req, res) => { try { const { id } = req.params; const userToModify = await User.findById(id); const currentUser = await User.findById(req.user._id); // 优先检查用户是否存在 if(!userToModify || !currentUser) return res.status(400).json({ message: "User not found!" }); // 通过_id字符串比较判断是否为自身 if(userToModify._id.toString() === currentUser._id.toString()) { return res.status(400).json({ message: "You cannot follow/unfollow yourself!" }); } const isFollowing = currentUser.following.includes(id); if (isFollowing) { // 取消关注逻辑 await User.findByIdAndUpdate(id, { $pull: { followers: req.user._id } }); await User.findByIdAndUpdate(req.user._id, { $pull: { following: id } }); res.status(200).json({ message: "User unfollowed successfully" }); } else { // 关注逻辑 await User.findByIdAndUpdate(id, { $push: { followers: req.user._id } }); await User.findByIdAndUpdate(req.user._id, { $push: { following: id } }); res.status(200).json({ message: "User followed successfully" }); } } catch (err) { res.status(500).json({ message: err.message }); console.log("Error in follow or unfollow User: ", err.message); } };
额外优化
可以用User.exists()替代完整文档查询,减少资源消耗:
const userExists = await User.exists({ _id: id }); const currentUserExists = await User.exists({ _id: req.user._id }); if(!userExists || !currentUserExists) return res.status(400).json({ message: "User not found!" });
二、HTTP方法的选择分析
现有POST方法是否合适?
POST是可行的,因为关注/取消关注本质是创建或删除用户间的关系,POST语义上适合处理这类非幂等操作(重复请求会切换状态)。但如果接口同时处理两种操作,POST的语义会略显模糊。
PATCH vs PUT
- PATCH:更贴合REST语义,因为你是在部分更新用户的关注列表(添加或移除单个项),PATCH专门用于资源的局部修改,语义更清晰。
- PUT:语义上是替换整个资源,若使用PUT通常需要传递完整的关注列表,不符合当前仅修改单个关系的场景,不推荐。
推荐方案
- 若严格遵循REST规范,优先选择PATCH,可在请求体中明确操作类型(比如
{ action: "follow" }),让接口逻辑更直观。 - 若保持现有自动切换状态的逻辑,POST也可接受,这是不少社交平台的常见实践。
内容的提问来源于stack exchange,提问作者Phoenix Phoenix
相关产品推荐
相关产品推荐

