问题描述
GET /apI/Orders
GET /apI/Orders/{orderId}
我在“订单”页面上有一些按钮,为此我创建了几个端点:
PATCH /apI/Order/buttons/mark-as-read
PATCH /apI/Order/buttons/change-status
现在我需要添加 delete
按钮。但我不明白该怎么做。我有两个选择:
-
DELETE /apI/Orders/{orderId}
- 但我应该在这个请求中发送 2 个额外的参数 -
PATCH /apI/Order/buttons/delete
- 我可以在正文中发送我的 DTO,但这不是 REST 方法。
我想了解 REST 上下文中的 delete
按钮使用哪种类型的请求?
解决方法
PATCH /api/order/buttons/mark-as-read
PATCH /api/order/buttons/change-status
这些有点奇怪。 PATCH 是一种具有远程创作语义的方法;这意味着您正在对由有效目标 URI 标识的资源进行更改。
但这里似乎并非如此;如果您希望将更改应用于由 /api/orders/{orderId} 标识的文档,则 that 应该是目标 URI,而不是其他一些资源。
PATCH /api/orders/1
Content-Type: text/plain
Please mark this order as read.
PATCH /api/orders/1
Content-Type: text/plain
Please change the status of this order to FULFILLED
当然,我们通常不会使用“text/plain”和需要人工解释的语句,而是使用可以教机器学习的补丁文档格式(例如:application/json-patch+json)解释。
我想了解 REST 上下文中的删除按钮使用哪种类型的请求?
如果“删除”的语义属于 Orders
域(例如,如果它是一个表示希望取消订单的按钮),那么您应该使用 PUT或 PATCH(如果您通过传递资源的更新表示进行通信)或 POST(如果您要发送服务器将解释的指令)。
要考虑的启发式方法:您将如何在纯 HTML 页面上执行此操作?大概您会有一个“取消我的订单”表单,其中包含用于收集用户信息的输入控件,以及一些可能的隐藏字段。当用户提交表单时,浏览器将使用表单数据和 HTML 的表单处理规则来创建信息的 application/x-www-form-urlencoded 表示,然后将该信息 POST 到由表单操作标识的资源.
表单动作可以是任何东西;您可以使用 /api/orders/1/cancel,类似于您的标记为已读和更改状态设计;但是如果您可以使用订单的标识符(也就是说,您正在更改的资源),那么您就可以免费获得标准化cache invalidation的优势。
对于单个消息处理程序来说是正常的,它在 transfer of documents over a network domain 中具有单一职责,例如 POST /api/orders/{orderId},解释有效负载并选择多个处理程序之一(更改状态,标记为已读,取消)在您的域中。
您提议使用以下内容:PATCH /api/orders/{orderId} 和 OrderUpdatesDto 作为请求正文中的 JSON 字符串?
有点。
这里有三个拨号:使用哪个有效请求 URI、使用哪个有效负载、使用哪种方法。
因为我想利用缓存失效,我将寻找使用:/api/order/{orderId} 作为有效请求 URI 的设计,因为这是我想要的响应的 URI无效。
使用类似 OrderUpdate 消息/命令/DTO 的 JSON 表示作为请求的有效负载是很好的。但这并不适合远程创作。所以instead of PATCH,I would use POST
POST /api/orders/1 HTTP/1.1
Content-Type: application/prs.pavel-orderupdate+json
{...}
但是您可以相反决定支持远程创作接口,这意味着客户端只需编辑他们的 /api/order/1 本地副本,然后告诉您他们所做的更改。
在这种情况下,PUT(发回整个文档)和 PATCH(发回一堆编辑)都有意义。如果 GET /api/orders/1
返回一个 JSON 文档,那么我将研究我是否可以支持通用 JSON 补丁文档格式之一; JSON Patch 或 JSON Merge Patch 或类似的东西。
当然,从“对文档的更改”到对非贫血域有意义的消息可能真的很难。有一些原因我们可能更喜欢支持 task based 体验,但是如果您还希望缓存按照我的方式工作,那么发送以任务为中心的 DTO 并不适合 PUT/PATCH如上所述。