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】:如果我猜对了,你有一个
起源 数据库 客户如果客户端GET
s 是book
,他会从数据库中获取资源。
数据库不知道这个book
是否同时被改变,它提供一个过时的版本?因此,您希望客户端向POST
或PUT
资源强制数据库从源再次获取条目?
想一想:
源缓存其内容,数据库缓存其内容,客户端也缓存。
如果用户按下 F5,客户端会重新加载资源,对吗?
这是一个好的行为吗?不。
客户端检查资源是否过时并且仅在必要时获取会更好吗?是的。
这可以通过发送HTTP-HEAD
向服务器询问上次修改的日期来实现,如果客户端检索日期较旧,他需要再次获取,否则他可以从缓存中提供服务。
同样适用于数据库/起源星座。数据库需要验证其内容是否仍然是请求的最新内容,并提供或从源获取它,更新缓存并提供新条目。
所以客户仍然会GET
资源,如果他不想以任何方式更改资源,那将是准确的。
【讨论】:
我更新了描述,使其更加清晰。简而言之:我正在构建一个 REST 服务来处理书籍缓存。加载/重新加载和删除操作只能由管理员执行,而 GET 对所有人开放。加载/重新加载操作应该从原始数据库加载/重新加载记录并将其放入缓存中。注意:同意 HEAD 将是一个有用的补充。【参考方案2】:我认为您不应该在资源路径中使用操作名称(例如/books/12345/reload
,...),因为它不是真正的 RESTful。也就是说,我同意你的观点,POST
方法是正确使用的方法。
IMO,您应该对资源路径 /books/12345
使用方法 POST
。它将对应一个动作加载/重新加载,并且可以是异步的,即为此资源返回一个状态代码202è. If you already have a method
POST`,您应该考虑使用这篇博文中描述的策略:https://templth.wordpress.com/2015/03/20/handling-multiple-actions-for-a-post-method/。
希望对你有帮助 蒂埃里
【讨论】:
以上是关于REST API 设计 - 通过 ID 加载创建资源的主要内容,如果未能解决你的问题,请参考以下文章
SpringBoot Rest API 中的 EntityManager 和 SessionHolder 错误