首页 > 解决方案 > PATCH 请求中的路径参数与查询参数

问题描述

我知道关于这个主题已经提出了许多最佳实践问题,但我无法准确找到我正在寻找的内容。假设我想要一个端点来加入或离开聊天室。我的想法是有一个请求,例如:

PATCH /api/chatroom/{roomId}?action=join|leave

这对我来说似乎很可靠,因为 PATCH 通常用于部分更新资源。在这种情况下,我正在更新聊天室资源,删除或添加成员。但是,我不喜欢这个,原因有两个:

  1. 有一个类似的查询参数action感觉有点笨拙。API 用户必须知道 的可能值action,并且必须在服务器端显式处理无效值。
  2. joinvs的错误处理完全不同leave。如果用户未被邀请到聊天室,加入请求将返回错误。另一方面,如果用户不是聊天室的成员,请假请求将返回错误。这种差异让我觉得这些应该是单独的端点。

最好有两个这样的端点吗?

PATCH /api/chatroom/{roomId}/joinPATCH /api/chatroom/{roomId}/leave

这感觉更糟,因为join并且leave不是资源。但是,我也喜欢这将事物分成两个端点。什么是 RESTful 方式来做到这一点?

标签: resthttp

解决方案


这对我来说似乎很可靠,因为 PATCH 通常用于部分更新资源。

是的……但我们通常不会仅仅为了修补它们而投入新资源。

TL;DR:可以使用 POST。当一切都是 HTML 和表单时,这就是我们在 Web 上所做的。

PATCH 和 PUT 一样,应该理解为带有附加约束的 POST 消息。POST 为通用客户提供了很少的关于正在发生的事情的上下文;但PATCH更具体 - patch 表示我们正在提议对请求目标进行编辑,而有效负载是描述对表示的更改的“补丁文档”。

换句话说,如果我们试图纠正网页上的拼写错误,PATCH(如 PUT)是一种我们会使用的方法。

Webber 2011很好地描述了关键思想:PATCH 是网络域上通用文档传输的一部分。有用的业务活动(如加入和离开聊天)是在资源模型中操作文档的副作用

例如,您可能会想象一个包含聊天中所有参与者列表的文档 - 如果您自己想加入聊天,您可以通过要求服务器将您的姓名添加到其参与者列表中来发出信号。

一个直接的设计是在聊天室本身(?)中包含参与者列表,因此请求可能如下所示:

POST /api/chatroom/12345 HTTP/1.1
Content-Type: application/x-www-form-urlencoded

action=join&user=Bob

如果 /api/chatroom/12345 是具有 JSON 表示的资源,那么我们可以通过修补聊天室资源中的参与者列表来获得类似的结果

PATCH /api/chatroom/12345 HTTP/1.1
Content-Type: application/json-patch+json

[
{ "op": "add", "path": "/participants", "value": "Bob" }
]

最好在正文中包含补丁的信息,而不是 URL。

URI 标识资源;补丁文档描述了对由 URI 标识的资源的建议更改。


我应该倾向于在资源本身上使用 PATCH,并传递我正在寻找的更改的 JSON 表示?

...如果远程创作是适合您的上下文的正确界面。

一种思考方式:在远程创作界面中,通过 PUT 还是通过 PATCH 对资源进行更改可能无关紧要。他们都表达了相同的基本思想(请使您的副本看起来像我的副本)。

这意味着推断预期的“业务活动”意味着识别文档中的更改,然后做正确的事情。将此与 POST 进行对比,后者更适合“我将告诉你我想要什么,你弄清楚文档应该如何更改”。


推荐阅读