REST API - 更新实体之间的关系

REST API - Update relationship between entities

这就是您在我的 API 中为作者添加图书的方式:

PUT /authors/1/books/1/

我现在想把这本书换成另一个作者。

我该怎么做?我在考虑以下选项。

1- 使 /authors 和 /books 成为顶级资源。使用书上的 属性 控制书的作者,例如 authorId: 2。例如,PUT /book/1 并在 body 中设置 authorId: 2 和其他属性。

2 - 执行 PUT /authors/2/books/1/,将现有作者的书更改为 2。使用此方法我应该检查该书是否已存在。如果存在,我更新作者和其他属性,如果不存在,我会创建一本新书。

就最佳实践而言,哪个是最佳选择?第二个选项是废话吗?

两者都是唯一可识别的,因此它们本身都应该是资源,即

GET /authors/1
GET /books/1

因此,您建议 IMO 的第二个选项似乎是最明智的,即

PUT /books/1

{ authorId: 2 }

好吧,让我假设一些..

  • 一本书一位作者
  • 你已经有了书的 id,因为它在你的语句中排在第一位,对吧
  • 您已经有了要设置的作者id

那么,让我强加一些东西..

POST /books/1
{
  op: 'set'
  entity: 'authorId'
  value: 2
}

(我并不是说这是最佳实践,只是举个例子)

URI 是一个标识符 - 从通用组件的角度来看,它在语义上是不透明的。有关资源当前状态的信息在表示中表达,而不是在标识符中。

I now want to change the book to another author.

作为客户端,执行此操作的通常方法是下载该书的副本,修改您的本地副本以引用新作者,然后向同一目标 uri 发出 PUT 请求你用来获取表示的。 PUT 语义要求服务器更改目标资源的服务器表示以匹配客户端的表示。

服务器可以将信息编码到 URI 中,但该信息仅供服务器使用。

是的,这意味着客户端可能会对与 URI 中表达的 "semantics" 冲突的表示进行编辑。这类似于文件名与其内容不对齐的情况。

服务器在了解通用请求的语义后,可以决定如何处理它。合理的选择包括

  • 拒绝请求
  • 接受就地编辑,留下标识符和表示之间的分歧
  • 在其他地方接受这些编辑,有效地创建(或编辑)新资源。

就让通用客户端将其理解与服务器更新后的资源模型相匹配而言,最后一个选项可能是最难做到的。