REST API 设计 - 最佳实践:链接现有子资源 [关闭]
Posted
技术标签:
【中文标题】REST API 设计 - 最佳实践:链接现有子资源 [关闭]【英文标题】:REST API design - best practice: Link existing child resource [closed] 【发布时间】:2017-07-13 04:38:28 【问题描述】:在设计 REST API 时,我了解如何添加(POST
)、更新(PUT
、PATCH
)等实体。但我想知道如何设计端点以将现有项目添加到现有资源?
这是一个示例:假设我们有一个 API,其中包含资源 Course
和 Student
以及以下端点:
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
- PUT
或 POST
并在正文中发送课程 ID。
http://localhost/students/2/courses/
- PUT
或 POST
并在正文中发送课程 ID。
...
有最佳实践吗?有什么建议吗?这应该通过courses
或students
资源处理吗?两者都应该是可能的吗?另外我不确定使用哪种方法(PUT
或POST
)?
PUT
或 POST
身体里什么都没有,感觉有点奇怪。另一方面,如果正文中的所有内容都是一个 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 设计 - 最佳实践:链接现有子资源 [关闭]的主要内容,如果未能解决你的问题,请参考以下文章