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



说我试图在MongoDB用Go编写的RESTful API中建模将学生添加到组的动作。

A Group的模型如下:

type Group struct {
Section mgo.DBRef
Instructor mgo.DBRef
Students []mgo.DBRef
}

一个额外的约束是API正在实现HAL+JSON协议,其中资源被表示为链接。

我看到了下面的几个选项:

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

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

如果有其他选择,我也愿意接受。

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

接下来的问题是如何从组中删除Student ?我可以用

向/groupmembership发送类似的DELETE请求吗?
{
  "student": 123,
  "group": 456
}

从456组移除123学生?

,其中资源表示为链接

这不是真的。链接可能是操作调用,因此它们表示可能的资源状态转换。

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

您可以通过两种方式识别成员:

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

指出:

  • URI结构仅从人的角度考虑。REST客户端将检查链接关系而不是URI结构。
  • 资源与数据库中的实体不同。只有通过简单的CRUD应用程序表示它们是相同的东西。所以REST与你的数据库结构无关。

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

只要从HTTP的角度来看一个选项不是错误的,我建议坚持使用与API的REST更一致的选项。

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

最新更新