针对深插入和浅插入选项的 REST 方法设计

问题描述 投票:0回答:1

我们正在设计 REST API 并拥有

course
student
实体:

  • 课程包括多名学生
  • 多个课程可以共享同一个学生
  • 创建课程时,应该能够包含现有学生(浅插入)并引用现有学生(深插入)。

哪个是最直观、最正确的选项:

  1. 有在父级别提供 id 和 body 的两个选项:
POST /courses
{
  "courseName" : "Java 8",
  "students" : [
    {
      "name" : "John Doe" // new student(deep insert)
    }
  ],
  "studentIds" : [
    123, 124              // existing students(shallow insert)
  ]
}
  1. 有在子级别提供 ids 和 body 的两种选项:
POST /courses
{
  "courseName" : "Java 8",
  "students" : [
    {
      "name" : "John Doe" // new student(deep insert)
    },
    {
      "studentId" :123    // existing student(shallow insert)
    },
    {
      "studentId" : 124   // existing student(shallow insert)
    }
  ]
}

这是此案例唯一的设计选择吗?

当子实体中同时存在 id 和 Payload 字段时(如上面的

student
实体所示),JSON 存在歧义是否可以接受?

这就是 REST 指南和其他问题通常涵盖的内容。

rest api-design
1个回答
0
投票

就 REST 而言,两个请求负载都是 fine。 REST 不限制通过网络发送的表示。

一个可能有用的类比:在网络上,我们通常通过表单将信息发送到网络服务器,并且我们有一个标准化的机制用于将信息从表单控件复制到请求正文中;但没有任何规则说“你必须这样设计你的表单”。

因此,如果您想将学生的完整表示与学生的摘要表示混合在一起,那没问题。如果您喜欢将它们分开,也可以。


寻找指导的正确位置不是 REST(同样,REST 并不关心文档的外观),而是消息模式设计的原则。

特别是,您需要注意模式是否可以以向后兼容的方式扩展,是否可以明确地传达/描述模式,以及是否可以明确地处理模式。

我的猜测:使用第一个模式你的生活会更轻松,因为你避免需要解释特定的 JSON 对象是完整的还是摘要的 - 你根据对象所在的列表“知道”答案。

有关消息设计的有用参考包括:

  • Greg Young 的 事件溯源系统中的版本控制
  • David Orchard 在 XML 词汇方面的工作
  • Kenton Varda 在 Protocol Buffers 方面的工作
© www.soinside.com 2019 - 2024. All rights reserved.