Express+Mongoose如何实现通讯录PUT请求更新已有联系人号码逻辑
问题解答
理解偏差修正
- 不需要在
app.post的逻辑内部调用app.put,二者是完全独立的路由处理逻辑,对应不同的前端请求场景:- POST请求对应新增全新的通讯录条目场景
- PUT请求对应更新已有通讯录条目场景,前端会直接把请求打到
/api/persons/:id这个带条目标识的URL上,不需要经过POST接口中转
具体实现逻辑
1. 先修改现有POST接口,避免重复添加同姓名条目
当前你的POST接口没有校验姓名重复,需要先加一层查询,同姓名的话直接返回错误,引导前端走PUT更新逻辑:
app.post('/api/persons', async (req, res) => { const body = req.body if (!body.name || !body.number) { return res.status(400).json({ error: "must specify a name and a number" }) } // 新增:查询是否已存在同姓名条目 const existPerson = await Person.findOne({ name: body.name }) if (existPerson) { return res.status(409).json({ error: "name already exists in the address book, please use update operation" }) } const phone = new Person({ name: body.name, number: body.number }) phone.save().then(savedPerson => { res.json(savedPerson) }) })
2. 新增独立的PUT路由处理更新请求
按照需求,前端会请求带条目ID的URL,所以路由要匹配/api/persons/:id,直接在该路由内做更新逻辑即可:
app.put('/api/persons/:id', async (req, res) => { const { id } = req.params const { number } = req.body // 校验参数合法性 if (!number) { return res.status(400).json({ error: "number is required for update" }) } // 使用findByIdAndUpdate方法更新,{ new: true }表示返回更新后的文档 const updatedPerson = await Person.findByIdAndUpdate( id, { number }, { new: true, runValidators: true, context: 'query' } ) if (updatedPerson) { res.json(updatedPerson) } else { res.status(404).json({ error: "the person to be updated does not exist" }) } })
3. 参数说明
new: true:配置Mongoose返回更新后的最新文档,而非更新前的旧文档runValidators: true:开启字段校验,确保更新的手机号符合你在Schema里定义的格式规则context: 'query':配合校验规则使用,避免部分校验逻辑失效
验证方式
启动后端服务后,先尝试添加重复姓名的条目,确认POST接口返回409错误,再调用PUT接口修改对应条目的手机号,确认返回更新后的信息,最后验证前端操作可以正常更新手机号即可。
内容的提问来源于stack exchange,提问作者421
相关产品推荐
相关产品推荐

