繁体   English   中英

REST、HTTP DELETE 和参数

[英]REST, HTTP DELETE and parameters

为 HTTP DELETE 请求提供参数有什么非 RESTful 的吗?


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

我们采用的解决方案是给删除请求传递一个参数,表示可以继续删除(“?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 客户端-服务器”,因为确认对话确实是一个 UI 问题,而且并非所有客户端都希望确认删除。

任何人的建议?

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

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

正如亚历克斯所说(我不知道谁对他投了反对票,他是对的),这应该在 UI 中处理,因为这样的 RESTful 服务只处理请求,因此应该是无状态的(即它不能依赖于通过持有确认有关请求的任何服务器端信息)。

如何在 UI 中执行此操作的两个示例是:

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

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


更新(基于额外的调查和讨论):

服务需要存在force_delete=true标志的场景违反了 Roy Fielding 的论文中定义的统一接口 此外,根据HTTP RFC , DELETE 方法可能会在源服务器(客户端)上被覆盖,这意味着这不是在目标服务器(服务)上完成的。

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

我认为这是不宁静的。 我认为 restful 服务不应该处理强制用户确认删除的要求。 我会在 UI 中处理这个问题。

如果这是程序的 API,那么指定 force_delete=true 是否有意义? 如果有人正在编写脚本来删除此资源,您是否要强制他们指定 force_delete=true 来实际删除该资源?

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

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

除了亚历克斯的回答:

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM