REST API 设计 - 最佳实践:链接现有子资源 [关闭]

Posted

技术标签:

【中文标题】REST API 设计 - 最佳实践:链接现有子资源 [关闭]【英文标题】:REST API design - best practice: Link existing child resource [closed] 【发布时间】:2017-07-13 04:38:28 【问题描述】:

在设计 REST API 时,我了解如何添加(POST)、更新(PUTPATCH)等实体。但我想知道如何设计端点以将现有项目添加到现有资源?

这是一个示例:假设我们有一个 API,其中包含资源 CourseStudent 以及以下端点:

http://localhost/students - POST 添加新学生 http://localhost/courses - POST 添加新课程 http://localhost/courses/1 - PUT 更新 ID 为 1 的课程 http://localhost/courses/1/students - GET 列出课程中 ID 为 1 的所有学生 http://localhost/courses/1/students - POST 将新学生添加到 ID 为 1 的课程中​​

问题是,我如何链接现有学生现有课程?澄清一下:“现有”是指系统中已经存在但尚未链接的资源。

我看到以下选项:

http://localhost/courses/1/students - PUT 并在正文中发送学生 ID。使用PUT 的理由是我正在“更新”课程的学生资源。 http://localhost/courses/1/students - POST 并在正文中发送学生 ID。使用POST 的原因是我在课程中“添加/创建”了一个新资源。 http://localhost/courses/1/students/2 - PUT 并在 URL 中发送 Id,在正文中不发送任何内容。 http://localhost/courses/1/students/2 - POST 并在 URL 中发送 Id,在正文中不发送任何内容。 http://localhost/students/2 - PUTPOST 并在正文中发送课程 ID。 http://localhost/students/2/courses/ - PUTPOST 并在正文中发送课程 ID。 ...

有最佳实践吗?有什么建议吗?这应该通过coursesstudents 资源处理吗?两者都应该是可能的吗?另外我不确定使用哪种方法(PUTPOST)?

PUTPOST 身体里什么都没有,感觉有点奇怪。另一方面,如果正文中的所有内容都是一个 Id,为什么不把它放在 URL 中呢?

【问题讨论】:

使用 PUT 请求使用localhost/students/1 更新 ID 为 1 的学生,并在发送的正文/数据中包含现有的课程 ID。这不适合你吗? 我正在考虑通过courses 资源添加学生,因为这似乎是“自然方式”。但你的方法肯定也会奏效。我只是想知道最好的方法是什么?也许这两种方法都是合适的。我会相应地更新问题。 【参考方案1】:

我认为关键在这里:

http://localhost/courses/1/students - POST 将新学生添加到 ID 为 1 的课程

鉴于您在此 URL 上使用 POST 将学生注册到课程中,因此无论学生是新学生还是现有学生都无关紧要。正如您所说,这可以是一个实现细节,例如在正文中发送现有学生的ID

【讨论】:

【参考方案2】:

问题是,如何将现有学生链接到现有课程?

作为一个网站,你会怎么做?

消费者将登陆他们的书签页面,并四处寻找一个链接,上面写着“注册学生”之类的内容。他们将通过该链接指向一个表格或一系列表格,这些表格将收集输入数据(学生的标识符、课程的标识符等)。然后消费者将提交包含所需信息的表单。

当网络服务器收到上一步提交的表单时,它会更新域模型作为副作用。

这样看来,“资源”不是学生,也不是课程,而是注册学生请求的收件箱

Jim Webber,来自他关于 REST 和领域驱动设计的演讲:

网络不是您的域,它是一个文档管理系统。所有 HTTP 动词都适用于文档管理域。 URI 不映射到域对象 - 这违反了封装。工作(例如:向域模型发出命令)是管理资源的副作用。

您将消息发布到收件箱资源,作为副作用,对学生或课程进行的任何必要更改都会在您的域中发生。

所以您应该采用的设计 URI 的方法是:

    想象一下网站的设计,以及消费者用来与之交互的协议 找出协议每个阶段的语义 将本地 URI 拼写约定应用于该语义,以确定每个资源的标识符

【讨论】:

以上是关于REST API 设计 - 最佳实践:链接现有子资源 [关闭]的主要内容,如果未能解决你的问题,请参考以下文章

设计 Node.js REST API 的 10 条最佳实践

06-Flask之REST&API设计

RESTFul API最佳实践

使用明文密码访问 REST API 的最佳实践

RESTful API 设计最佳实践

10个有关RESTful API良好设计的最佳实践