Мой код ниже не позволяет пользователю API обновлять только одно поле, передавая одно свойство запроса. Я могу удалить нуль в userObj
, но разработчик пользовательского интерфейса должен будет передать существующие данные из базы данных, чтобы сделать обновление, что не является лучшей практикой.
Вот мой экспресс-маршрут:
router.put('/user', (req, res) => {
const userObj = {
name: req.body.name || null,
location: {
city: req.body.city || null
},
phone: req.body.phone || null
};
User.updateUser(req.body.id, userObj)
});
Вот моя монгольская модель updateUser
:
module.exports.updateUser = (_id, userObj, callback) => {
User.findOneAndUpdate({_id}, userObj, { upsert: true, 'new': true }, callback);
}
Во-первых, чтобы решить проблему с обновлением только нескольких определенных свойств, вам нужно использовать оператор $set
для установки только определенного поля. Когда вы передаете userObj
прямо в findOneAndUpdate
вы findOneAndUpdate
весь объект, таким образом, вы должны передать все существующие свойства. Используйте $set
:
User.findOneAndUpdate({_id}, { $set: userObj }, { upsert: true, new: true }, callback);
Это обновит только свойства, определенные в userObj
к их новым значениям и больше ничего не коснется. Кроме того, вы можете просто использовать findByIdAndUpdate
для этого самого случая использования:
User.findByIdAndUpdate(_id, { $set: userObj }, { upsert: true, new: true }, callback);
Затем вы не должны использовать PUT. Используйте PATCH. PUT означает размещение ресурса на каком-то URL-адресе и его замену полностью, если он уже существует. PATCH означает, что вы обновляете только несколько свойств ресурса и заменяете все это. Это не повлияет на функциональность приложения, но это огромная проблема семантики и проблема конечного пользователя, так как они ожидали бы PATCH.
Использовать $ set
User.findOneAndUpdate({_id}, {$set: userObj}, /* ... */)
$set
независимо , если вы используетеfindByIdAndUpdate
илиfindOneAndUpdate
, если вы хотите обновить только один или более специфических свойств.