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

时间:2017-07-13 04:38:29

标签: web-services rest http asp.net-web-api restful-url

在设计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并发送学生身份证明。使用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 - PUTPOST并在正文中发送课程ID。
  • http://localhost/students/2/courses/ - PUTPOST并在正文中发送课程ID。
  • ...

有最佳做法吗?有什么建议?是应该通过courses还是students资源处理?两者都应该可行吗?另外,我不确定使用哪种方法(PUTPOST)?

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

2 个答案:

答案 0 :(得分:2)

我认为关键在于:

  

http://localhost/courses/1/students - POST将新学生添加到   当然是Id 1

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

答案 1 :(得分:0)

  

问题是,如何将现有学生与现有课程联系起来?

你会如何将其作为一个网站?

消费者将登陆他们的书签页面,并环顾四周寻找类似于"注册学生"的链接。他们将遵循链接到表单或一系列表单,这些表单将收集输入数据(学生的标识符,课程的标识符等)。然后,消费者将提交包含所需信息的表格。

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

以这种方式观察,"资源"不是学生或课程,而是用于注册学生请求的收件箱

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

  

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

您将邮件发布到收件箱资源,并且作为副作用对学生或课程进行必要的更改,将在您的域中发生。

因此,您应该采用的方法来设计URI;

  1. 想象一下网站的设计,以及消费者用来与之互动的协议
  2. 弄清楚协议各阶段的语义
  3. 将您的本地URI拼写约定应用于该语义,以确定每个资源的标识符