Web services RESTAPI设计-最佳实践:链接现有子资源

Web services RESTAPI设计-最佳实践:链接现有子资源,web-services,rest,http,asp.net-web-api,restful-url,Web Services,Rest,Http,Asp.net Web Api,Restful Url,在设计RESTAPI时,我了解如何添加实体(POST)、更新实体(PUT、补丁)等等。但是我想知道如何设计端点来将现有项添加到现有资源中 下面是一个示例:假设我们有一个API,其中包含课程和学生资源以及以下端点: http://localhost/students-POST添加新学员 http://localhost/courses-POST添加新课程 http://localhost/courses/1-放置以更新Id为1的课程 http://localhost/courses/1/stud

在设计RESTAPI时,我了解如何添加实体(
POST
)、更新实体(
PUT
补丁
)等等。但是我想知道如何设计端点来将现有项添加到现有资源中

下面是一个示例:假设我们有一个API,其中包含
课程
学生
资源以及以下端点:

  • http://localhost/students
    -
    POST
    添加新学员
  • http://localhost/courses
    -
    POST
    添加新课程
  • http://localhost/courses/1
    -
    放置
    以更新Id为1的课程
  • http://localhost/courses/1/students
    -
    获取
    以列出Id为1的所有课程学生
  • http://localhost/courses/1/students
    -
    POST
    向课程添加Id为1的新学员
问题是,我如何将现有学生链接到现有课程?澄清一下:我所说的“现有”是指系统中已经存在但尚未链接的资源

我看到以下选择:

  • http://localhost/courses/1/students
    -
    放入并发送学生Id。使用
    PUT
    的理由是我正在“更新”课程的学生资源
  • http://localhost/courses/1/students
    -
    发布
    并在正文中发送学生Id。使用
    POST
    的原因是我正在课程中“添加/创建”一个新资源
  • http://localhost/courses/1/students/2
    -
    放入URL中并发送Id,而在正文中不发送任何内容
  • http://localhost/courses/1/students/2
    -
    发布
    并在URL中发送Id,在正文中不发送任何内容
  • http://localhost/students/2
    -
    发布
    并将课程Id发送到正文中
  • http://localhost/students/2/courses/
    -
    发布
    并将课程Id发送到正文中
是否有最佳实践?有什么建议吗?这应该通过
课程
学生
资源处理吗?两者都应该是可能的吗?此外,我不确定使用哪种方法(
PUT
POST


身体里什么都没有的
感觉有点奇怪。另一方面,如果主体中的所有内容都是一个Id,为什么不将其放在URL中呢

我认为关键在于:

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

鉴于您正在使用此
URL
上的
POST
将学生注册到课程中,因此该学生是新学生还是现有学生并不重要。正如您所说,这可能是一个实现细节,比如在正文中发送现有学生的
ID

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

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

消费者会登陆他们的书签页面,四处寻找类似“注册学生”的链接。他们将按照链接到一个表单或一系列表单,以收集输入数据(学生标识符、课程标识符等)。然后消费者将提交包含所需信息的表格

当web服务器收到在最后一步中提交的表单时,它会作为副作用更新域模型

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

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

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

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

因此,您应该采取的设计URI的方法是:

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

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