REST,HTTP DELETE和参数

时间:2010-03-29 16:01:24

标签: http rest

是否有任何关于为HTTP DELETE请求提供参数的非RESTful?


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

我们采用的解决方案是将参数传递给删除请求以指示可以继续删除(“?force_delete = true”)

e.g。

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's dissertation

的5.1.5节)

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

您还可能认为它违反了“5.1.2客户端 - 服务器”,因为确认对话确实是一个UI问题,并且并非所有客户都希望确认删除。

建议任何人?

4 个答案:

答案 0 :(得分:75)

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

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

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

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

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

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


更新 (基于其他调查和讨论):

服务需要force_delete=true标志存在的情况违反了Roy Fielding的论文中定义的uniform interface。此外,根据HTTP RFC,可以在源服务器(客户端)上覆盖DELETE方法,这意味着在目标服务器(服务)上不会这样做。

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

答案 1 :(得分:34)

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

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

答案 2 :(得分:16)

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

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

答案 3 :(得分:5)

除了Alex的回答:

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

是一个巨大的差异