REST、 HTTP DELETE 和参数

为 HTTPDELETE 请求提供参数是否有非 RESTful 的内容?


我的设想是,我正在建模“你确定要删除它吗?”场景。在某些情况下,资源的状态表明请求的删除可能无效。您可以自己想象一些需要确认删除的场景

我们采用的解决方案是向 delete 请求传递一个参数,以指示继续执行 delete (”?Force _ delete = true”)

例如:。

DELETE http://server/resource/id?force_delete=true

我相信它仍然是宁静的,因为:

(a) DELETE 的语义没有改变-用户仍然可以发送一个普通的 DELETE 请求,但是这个带有409和响应主体的 可能会失败将解释原因。我说可能失败是因为(由于不值得解释的原因)在某些情况下没有理由提示用户。

(b) Roy 的论文中没有任何内容表明它违背了 REST 的精神——既然 HTTP 只是 REST 的一个实现,那么传递 HTTP 参数又有什么关系呢


有没有人能给我一个明确的声明,说明为什么这不是 RESTful?

关于一个相关的问题,如果用户没有指定 force _ delete,那么我将返回 409 Conflict-这是最合适的响应代码吗?


跟进

经过进一步的研究,我认为在 DELETE 中添加参数可能会违反几个原则。

首先,实现可能违反了“统一接口”(参见 Roy 的论文的5.1.5节)

通过添加“ force _ DELETE”,我们在已经定义好的 DELETE 方法上添加了一个额外的约束。这种约束只对我们有意义。

您还可以认为它违反了“5.1.2 Client-Server”,因为确认对话实际上是一个 UI 问题,而且并非所有客户端都希望确认删除。

有人有建议吗?

142284 次浏览

我觉得这太不安宁了。我不认为 restful 服务应该处理强制用户确认删除的要求。我会在用户界面中处理这个问题。

如果这是一个程序的 API,指定 force _ delete = true 有意义吗?如果有人正在编写删除该资源的脚本,您是否希望强制他们指定 force _ delete = true 以实际删除该资源?

不,它不是 RESTful。将动词(force_delete)放入 URI 的唯一原因是,如果需要在 PUT/DELETE 方法不可用的环境中重载 GET/POST 方法。从您使用的 DELETE 方法判断,情况并非如此。

HTTP 错误代码 409/Conflict应该用于存在冲突的情况,这种冲突会阻止 RESTful 服务执行操作,但用户仍有可能自己解决冲突。预删除确认(没有阻止删除的真正冲突)本身不是冲突,因为没有任何东西阻止 API 执行请求的操作。

正如 Alex 所说(我不知道是谁否决了他,他是正确的) ,这应该在 UI 中处理,因为像 RESTful 这样的服务只处理请求,因此应该是无状态的(也就是说,它不能依赖于通过保存关于请求的任何服务器端信息的确认)。

在 UI 中如何做到这一点的两个例子是:

  • Pre-HTML5 : * 向用户显示一个 JS 确认对话框,只有在用户确认后才发送请求
  • HTML5 : * 使用一个包含动作 DELETE 的表单,其中表单将只包含“确认”和“取消”按钮(“确认”将是提交按钮)

(*)请注意,5之前的 HTML 版本本身不支持 PUT 和 DELETE HTTP 方法,但是大多数现代浏览器可以通过 AJAX 调用实现这两种方法。有关跨浏览器支持的详细信息,请参阅 这根线


更新 < em > (根据进一步的调查和讨论) :

服务需要出现 force_delete=true标志的场景违反了 Roy Fielding 论文中定义的 统一界面。此外,根据 HTTP RFC,DELETE 方法可能在原始服务器(客户机)上被重写,这意味着在目标服务器(服务)上不会这样做。

因此,一旦服务收到一个 DELETE 请求,它就应该处理它,而不需要任何额外的确认(无论服务是否实际执行操作)。

除了 Alex 的回答:

请注意,http://server/resource/id?force_delete=true标识的资源与 http://server/resource/id不同。例如,删除 /customers/?status=old还是 /customers/有很大的不同。

这是一个老问题,但这里有一些评论..。

  1. 在 SQL 中,DELETE 命令接受一个参数“ CASCADE”,该参数允许您指定也应该删除依赖对象。这是一个有意义的 DELETE 参数示例,但是“ manrm”可以提供其他参数。在没有参数的情况下,如何在 REST/HTTP 中实现这些情况?
  2. @ Jan,URL 的路径部分标识一个资源,而查询字符串不标识(至少不一定) ,这似乎是一个公认的约定。例子比比皆是: 获取相同的资源但格式不同,获取资源的特定字段,等等。如果我们认为查询字符串是资源标识符的一部分,那么如果不求助于非 RESTful 机制,比如 HTTP 内容协商(由于许多原因,这可能是不受欢迎的) ,就不可能有“同一资源的不同视图”的概念。