如何使用 REST 从子文档数组中发布、修补和删除项目

Posted

技术标签:

【中文标题】如何使用 REST 从子文档数组中发布、修补和删除项目【英文标题】:How to POST, PATCH and DELETE items from a subdocument array using REST 【发布时间】:2019-09-26 09:51:15 【问题描述】:

假设我们有以下用户文档:


  "_id": "1",
  "firstName": "Joe",
  "hobbies": [
     "_id": "1",
     "name": "music",
     "talented": true
   ],

假设我们想要发布、修补或删除 Joey 的一项爱好。 我们应该如何继续使用rest api?

我想过做这样的事情:

POST - /users/:id/hobbies


PATCH - /users/:id/hobbies/:id


DELETE - /users/:id/hobbies/:id

这看起来非常语义化且易于阅读,但另一方面,将子文档名称作为资源附加到路由中感觉不对,因为它是子文档并且属于主用户文档。

所以,我认为的另一种方法是简单地为主用户文档打补丁:

PATCH - /users/:id/

哪种休息路线结构对于完成这些任务是正确的?

【问题讨论】:

【参考方案1】:

假设我们有以下用户文档 我们应该如何继续使用rest api?

将文档视为文档:在本地进行编辑,然后将结果发送回服务器。

假设此文档在/users/1/ 上可用,我们将只发回一份删除了爱好的表示...

PUT /users/1/


  "_id": "1",
  "firstName": "Joe",
  "hobbies": [
   ],

使用 PATCH 代替 PUT 很好(假设我们发送一个补丁文档作为消息体)。从技术上讲,您也可以使用 POST,但 POST 在这里并没有真正为您提供任何优势。

/users/:id/hobbies
/users/:id/hobbies/:id

使用这样的标识符的问题在于,通用客户端无法识别它们与 /users/:id/ 有任何关系 - 因此,即使您发送消息以删除爱好,客户端的本地缓存副本也不会得到更新(因为它使用不同的密钥)。

现在,如果您的资源是使用 链接

设计的

  "_id": "1",
  "firstName": "Joe",
  "hobbies": [  "href": "/users/1/hobbies/4"  ]

然后我们仍将使用/users/1/ 从集合中添加/删除爱好,但如果我们想修改爱好本身的表示,那么我们将使用/users/1/hobbies/4 发送消息。

如果爱好集合本身是一个链接...


  "_id": "1",
  "firstName": "Joe",
  "hobbies": "/users/1/hobbies"

然后我们会通过向/users/1/hobbies发送消息来添加/删除爱好。

考虑网页可能会有所帮助 - 网页的 html 表示通常包含指向图像或脚本的链接,这些链接与页面本身分开获取和缓存。如果我们想编辑 HTML,我们将使用页面的标识符发送请求,如果我们想更改脚本,我们将发送脚本的标识符。

【讨论】:

以上是关于如何使用 REST 从子文档数组中发布、修补和删除项目的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 REST API 从子集中删除项目

用于从子资源列表中更新/添加/删除项目的 REST 设计

如何根据查询从子文档数组中更新子文档字段?

Mongoose - 从子文档中删除属性

如何从子图中完全删除图并正确调整大小?

春季启动查询以单独从子文档数组中的字段中获取最大值