REST API 设计 - 通过 ID 加载创建资源

Posted

技术标签:

【中文标题】REST API 设计 - 通过 ID 加载创建资源【英文标题】:REST API Design - Create Resource By Loading By ID 【发布时间】:2015-05-08 09:16:37 【问题描述】:

我的 REST 服务需要支持加载/重新加载资源与直接创建资源的能力。

到目前为止的 API:

GET /books
GET /books/12345
DELETE /books/12345

一本书看起来像:

"id": 12345, "title": "three little bears", "author": ...

不清楚

Request:  PUT /books/12345
Response: HTTP 204 No Content

Request:  POST /books
Payload:  "id": 12345
Response: HTTP 201 Created, Location: /books/12345

是“加载”/“重新加载”图书的更好方法。

详细信息:“加载”/“重新加载”将查询数据库以通过 id 检索图书,并将结果放入持久缓存中。缓存是 GET 请求所咨询的。这本书的属性可以在数据库中更改,这意味着“加载”/“重新加载”不是幂等的。只有管​​理员才能使用加载/重新加载和删除操作。

相信正确的方法是 POST,因为 PUT 应该是幂等的。但是,POST 似乎很奇怪,因为针对 id=12345 的 /book 的多个 POST 只会导致创建单个资源(尽管会重新创建多次)

我已经考虑过以下其他选项,但它们似乎更令人震惊:

* POST /books/12345/load
* POST /books/load, with payload "id": 12345
* POST /load/book, with payload "id": 12345

想法?

为了使事情进一步复杂化,我还想提供一个异步加载/重新加载操作,但我不想创建用户可以跟踪的操作/作业资源,我只想要一个即发即弃.

示例:对于 Book 12345,异步加载/重新加载到缓存中。我只需要该服务以 HTTP 202 Accepted 进行响应,这就足够了。无需询问加载/重新加载的进度。

TL;DR:我正在构建一个 REST 服务来处理书籍缓存。加载/重新加载和删除操作只能由管理员执行,而 GET 对所有人开放。加载/重新加载操作应该从数据库加载/重新加载记录。

【问题讨论】:

【参考方案1】:

如果我猜对了,你有一个

起源 数据库 客户

如果客户端GETs 是book,他会从数据库中获取资源。 数据库不知道这个book是否同时被改变,它提供一个过时的版本?因此,您希望客户端向POSTPUT 资源强制数据库从源再次获取条目?

想一想:

源缓存其内容,数据库缓存其内容,客户端也缓存。

如果用户按下 F5,客户端会重新加载资源,对吗? 这是一个好的行为吗?不。 客户端检查资源是否过时并且仅在必要时获取会更好吗?是的。 这可以通过发送HTTP-HEAD 向服务器询问上次修改的日期来实现,如果客户端检索日期较旧,他需要再次获取,否则他可以从缓存中提供服务。

同样适用于数据库/起源星座。数据库需要验证其内容是否仍然是请求的最新内容,并提供或从源获取它,更新缓存并提供新条目。

所以客户仍然会GET 资源,如果他不想以任何方式更改资源,那将是准确的。

【讨论】:

我更新了描述,使其更加清晰。简而言之:我正在构建一个 REST 服务来处理书籍缓存。加载/重新加载和删除操作只能由管理员执行,而 GET 对所有人开放。加载/重新加载操作应该从原始数据库加载/重新加载记录并将其放入缓存中。注意:同意 HEAD 将是一个有用的补充。【参考方案2】:

我认为您不应该在资源路径中使用操作名称(例如/books/12345/reload,...),因为它不是真正的 RESTful。也就是说,我同意你的观点,POST 方法是正确使用的方法。

IMO,您应该对资源路径 /books/12345 使用方法 POST。它将对应一个动作加载/重新加载,并且可以是异步的,即为此资源返回一个状态代码202è. If you already have a methodPOST`,您应该考虑使用这篇博文中描述的策略:https://templth.wordpress.com/2015/03/20/handling-multiple-actions-for-a-post-method/。

希望对你有帮助 蒂埃里

【讨论】:

以上是关于REST API 设计 - 通过 ID 加载创建资源的主要内容,如果未能解决你的问题,请参考以下文章

REST API 与非 RE​​ST API [关闭]

SpringBoot Rest API 中的 EntityManager 和 SessionHolder 错误

Azure CosmosDB (16) 通过REST API对CosmosDB进行跨分区查询

在 Rest API 中批量更新

PayPal Rest API 创建付款不返回销售 ID

REST api:在一次获取中请求多个资源[重复]