更新时我们需要发送所有的字段,而不仅仅是要更新的字段吗?

更新时我们需要发送所有的字段,而不仅仅是要更新的字段吗?

在做fullstackopen的练习的时候,对这个题目描述不解?当我们只需更新likes字段,需要将其他的字段信息也放到请求中吗?

image.png

对这个项目做一个简短的介绍
使用到的一些技术: mongodbreactaxios(用于前端和后端通信)、expressrestful
后端相关的操作如下所示

blogRouter.put("/:id", async (request, response) => {
  const body = request.body;
  const blog = {
    title: body.title,
    author: body.author,
    url: body.url,
    likes: body.likes,
  };
  const updateBlog = await Blog.findByIdAndUpdate(request.params.id, blog, {
    new: true,
    runValidators: true,
  }).populate("user", { username: 1, name: 1 });
  if (updateBlog) {
    response.send(updateBlog);
  } else {
    response.status(404).end();
  }
});
  • 经过测试发现,findByIdAndUpdate应该只会更新我们通过参数传送的字段,而其他的会保持不变。
  • 我使用postman测试,只需要发送一个likes字段的信息就可以达到预期的效果,只更改了likes字段,其他保持不变。
    那为什么题目还说要发送所有的字段呢?
    image.png

博客的schema定义

const mongoose = require("mongoose");

const blogSchema = new mongoose.Schema({
  title: { type: String, required: true },
  author: String,
  url: { type: String, required: true },
  likes: { type: Number, default: 0 },
  user: {
    type: mongoose.Schema.Types.ObjectId,
    ref: "User",
  },
});

// https://mongoosejs.com/docs/api/document.html#Document.prototype.toJSON()
blogSchema.set("toJSON", {
  transform: (doc, ret) => {
    // transform the unqiue identifier into a string representing.
    ret.id = ret._id.toString();
    delete ret._id;
    // we don't require information about the mongodb version.
    delete ret.__v;
  },
});
module.exports = mongoose.model("Blog", blogSchema);
阅读 1.1k
avatarAI BotBETA

在 RESTful API 设计中,通常,当你要更新一个资源时,你只需要发送需要更新的字段。这是因为 HTTP PUT 方法是幂等的,意味着多次执行相同的请求应该产生相同的结果。如果你只发送需要更新的字段,那么无论请求被发送多少次,结果都是一致的。

在你给出的示例中,你的后端路由只更新了传入请求体(request.body)中的字段。如果 request.body 只包含 likes 字段,那么只有 likes 字段会被更新。其他字段将保持不变。

关于题目中提到的“更新时我们需要发送所有的字段,而不仅仅是要更新的字段吗?”这个问题,可能是为了强调在某些情况下,你可能需要发送所有字段。例如:

  1. 数据一致性:如果你的应用逻辑依赖于某个字段始终存在,并且不希望它被意外地删除或更改,那么你可能需要始终发送该字段,即使它的值没有变化。
  2. 前端状态管理:在某些前端框架中,发送所有字段可以确保前端的状态与后端保持一致。这可以避免因为只发送了部分字段而导致的状态不一致问题。
  3. 简化逻辑:对于一些简单的资源更新,发送所有字段可能使逻辑更简单,因为你不需要跟踪哪些字段已经更改,哪些字段需要发送。

然而,这并不是一个硬性规定。在实际应用中,你应该根据你的具体需求和应用的逻辑来决定是否需要发送所有字段。在你的情况下,如果 findByIdAndUpdate 方法只更新传入的字段,并且你通过测试验证了这一点,那么你就没有必要在每次更新时都发送所有字段。

1 个回答

(脑子一时锈掉了)后端操作要提取出博客的author、url、likes等信息,如果我只包含likes的话,其他的值就是会是undefined,这些undefined将会作为值取更新对应的字段,所以要将其他的也一并包含。

blogRouter.put("/:id", async (request, response) => {
  const body = request.body;
  const blog = {
    title: body.title,
    author: body.author,
    url: body.url,
    likes: body.likes,
  };
  const updateBlog = await Blog.findByIdAndUpdate(request.params.id, blog, {
    new: true,
    runValidators: true,
  }).populate("user", { username: 1, name: 1 });
  if (updateBlog) {
    response.send(updateBlog);
  } else {
    response.status(404).end();
  }
});
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进