Mongodb 将项添加到数组字段的正确REST端点是什么?

Mongodb 将项添加到数组字段的正确REST端点是什么?,mongodb,rest,Mongodb,Rest,假设我正试图在用Go with MongoDB编写的RESTful API中对向组中添加学生的操作进行建模 组的建模如下所示: 另一个约束是API正在实现协议,其中资源表示为链接 我看到了几个选项(如下所示): POST/groups/{groupID}/students/{studentID}将向组中添加studentID为的学生。这种方法的问题在于,由于我正在实现HAL+JSON协议,我不希望客户端手动提取ID并生成此链接。所有资源都将被表示,即/person/123可以是学生 将/gr

假设我正试图在用Go with MongoDB编写的RESTful API中对向组中添加学生的操作进行建模

组的建模如下所示:

另一个约束是API正在实现协议,其中资源表示为链接

我看到了几个选项(如下所示):

  • POST/groups/{groupID}/students/{studentID}将向组中添加studentID为的学生。这种方法的问题在于,由于我正在实现HAL+JSON协议,我不希望客户端手动提取ID并生成此链接。所有资源都将被表示,即
    /person/123
    可以是学生

  • 将/groups/{groupID}放入,同时发送应属于该组的完整学生数组。这似乎会引入很多复杂的解析逻辑

如果还有其他选择,我也会接受的

编辑:我将采用以下方法: *POST/groupmembership/通过发送带有学生ID和要添加学生的组ID的JSON。但是,在后端,我不会生成新模型,而是获取对象并以编程方式将指定的学生添加到指定的组中

接下来的问题是,我将如何从小组中删除该学生?我是否可以使用向/groupmembership发送类似的删除请求

{
  "student": 123,
  "group": 456
}
将学生123从456组中删除

其中资源表示为链接

事实并非如此。链接可能是操作调用,因此它们表示可能的资源状态转换

要向集合中添加内容,您需要一个集合资源,并且必须决定要在该集合中存储的内容。在您的情况下,这可以是两件事:团体学生会员或学生。如果这是1:n关系,则可以存储学生并删除学生。如果这是一个n:m关系,那么您必须存储成员身份并删除成员身份,因为您不想从存储中删除学生,只需删除成员身份即可

您可以通过两种方式确定会员资格:

  • 您可以使用参与者的ID:
    /groups/1/会员资格/student:1
    /students/1/会员资格/groups:1
  • 您可以为每个成员添加唯一的id:
    /memberships/1234
注:

  • URI结构只从人的角度起作用。REST客户端将检查链接关系,而不是URI结构
  • 这些资源与数据库中的实体不同。只有通过简单的CRUD应用程序才能表示相同的内容。所以REST与您的数据库结构无关

首先,没有正确的REST端点。URL语义与REST无关。重要的是URL是从超文本获得的,而不是从带外信息获得的,而且这一部分似乎是正确的,因为您使用的是HAL。因此,正确的REST端点是服务器为添加项目而提供给客户端的任何链接

只要一个选项从HTTP的角度来看是正确的,我会说坚持使用与API其余部分更一致的选项


POST/groups/{groupID}/students/{studentID}
以在该位置创建新学生的选项是不正确的,因为POST正在提交要由目标资源处理的负载,在这种情况下,它还不存在。一种常见的模式是使用
POST/groups/{groupID}/students
,其中集合充当新元素的facory,在有效负载中使用创建参数,并在位置标头中返回创建的学生URL,带有201个HTTP状态代码

问题是,您允许来自底层关系数据库的工件(在n:m关系中需要一个链接表)泄漏到API设计中。API不必直接映射到数据库模型。API不需要成员资源来表示多个组中的学生。没有人说,您需要一个关系数据库,或者API必须映射到数据库模型。成员资格是n:m关系的最佳实践。如果您没有其他元数据,并且不想向成员身份添加聚合id,那么您可以简单地使用
/memberships/group:{groupId}+student:{studentId}
URL。这意味着需要一个链接表,这是关系数据库设计的产物。对于n:m关系没有REST最佳实践,因为REST对URL语义和建模没有发言权。即使有元数据并且它存储为关系数据库中的成员链接表,RESTAPI中也不需要成员资源。。。顺便说一句,REST与域模型或关系数据库结构无关,它只是一种交付方法,所以我不知道您在说什么。。。
{
  "student": 123,
  "group": 456
}