在设计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
并发送学生身份证明。使用PUT
的论据是我“更新”课程的学生资源。http://localhost/courses/1/students
- POST
并发送学生身份证明。使用POST
的原因是我在课程中“添加/创建”了一个新资源。http://localhost/courses/1/students/2
- PUT
并在网址中发送身份证明,但身体中没有任何内容。http://localhost/courses/1/students/2
- POST
并在网址中发送身份证明,但身体中没有任何内容。http://localhost/students/2
- PUT
或POST
并在正文中发送课程ID。http://localhost/students/2/courses/
- PUT
或POST
并在正文中发送课程ID。有最佳做法吗?有什么建议?是应该通过courses
还是students
资源处理?两者都应该可行吗?另外,我不确定使用哪种方法(PUT
或POST
)?
PUT
或POST
在身体中没有任何东西感觉很奇怪。另一方面,如果正文中的所有内容都是Id,为什么不把它放在URL中呢?
答案 0 :(得分:2)
我认为关键在于:
http://localhost/courses/1/students
-POST
将新学生添加到 当然是Id 1
鉴于您在此POST
上使用URL
通常会将学生注册到课程中,无论学生是新人还是现有学生都无关紧要。正如您所说,这可以是一个实现细节,例如将现有学生的ID
发送到正文中。
答案 1 :(得分:0)
问题是,如何将现有学生与现有课程联系起来?
你会如何将其作为一个网站?
消费者将登陆他们的书签页面,并环顾四周寻找类似于"注册学生"的链接。他们将遵循链接到表单或一系列表单,这些表单将收集输入数据(学生的标识符,课程的标识符等)。然后,消费者将提交包含所需信息的表格。
当Web服务器收到上一步提交的表单时,它会将域模型更新为副作用。
以这种方式观察,"资源"不是学生或课程,而是用于注册学生请求的收件箱。
Jim Webber,他关于REST和域驱动设计的演讲:
网络不是您的域名,它是一个文档管理系统。所有HTTP谓词都适用于文档管理域。 URI不会映射到域对象 - 这违反了封装。工作(例如:向域模型发出命令)是管理资源的副作用。
您将邮件发布到收件箱资源,并且作为副作用对学生或课程进行必要的更改,将在您的域中发生。
因此,您应该采用的方法来设计URI;