You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

用户自我关注限制失效问题排查及HTTP请求方法选型咨询

问题解决:自我关注限制失效与HTTP方法选择

一、自我关注判断失效的修复

你的判断逻辑if(userToModify === currentUser)不生效,核心原因是Mongoose查询返回的是独立的文档对象,即使是同一个用户,两个对象的内存引用不同,全等比较会返回false。

修复步骤

  1. 调整判断顺序:先检查用户是否存在,再判断是否为自身(避免用户不存在时的无效判断)
  2. 比较用户的_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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 01:42:10