代码之家  ›  专栏  ›  技术社区  ›  Chris McCauley

REST、HTTP删除和参数

  •  121
  • Chris McCauley  · 技术社区  · 14 年前

    为HTTP删除请求提供参数是否有任何不可恢复的地方?


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

    我们采用的解决方案是向删除请求传递一个参数,以指示继续删除(“?”强制删除=真“)

    例如

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

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

    (a)删除的语义没有改变-用户仍然可以发送一个正常的删除请求,但是 可能失败 用409和正文来解释为什么。我说可能会失败,因为在某些情况下,没有理由提示用户。

    (b)Roy的论文中没有任何内容表明它违背了REST的精神——为什么会有HTTP,因为HTTP只是REST的一个实现,所以为什么传递HTTP参数很重要?


    有人能指点我一个明确的声明,指出为什么这不安逸的原因吗?

    在相关问题上,如果用户没有指定强制删除,那么我将返回 409 Conflict -这是最合适的响应代码吗?


    跟进

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

    第一,实现可能违反“统一接口”(见第5.1.5节 Roy's dissertation

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

    您也可以认为它违反了“5.1.2客户机服务器”,因为确认对话实际上是一个用户界面问题,而且并非所有客户机都希望确认删除。

    有人建议吗?

    4 回复  |  直到 9 年前
        1
  •  75
  •   Community Aniket Inge    7 年前

    不,这不舒服。你应该放动词的唯一原因( force_delete )如果您需要在Put/Delete方法不可用的环境中重载get/post方法,则进入URI。从你使用的删除方法来看,情况并非如此。

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

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

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

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

    (*)请注意,5之前的HTML版本本机不支持Put和Delete HTTP方法,但是大多数现代浏览器可以通过Ajax调用来实现这两种方法。见 this thread 有关跨浏览器支持的详细信息。


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

    服务需要 force_delete=true 存在的标志违反了 uniform interface 正如罗伊·菲尔丁的论文中所定义的。此外,按 HTTP RFC ,可以在源服务器(客户端)上重写delete方法,这意味着在目标服务器(服务)上不执行此操作。

    因此,一旦服务收到一个删除请求,它应该在不需要任何额外确认的情况下处理它(不管服务是否实际执行了操作)。

        2
  •  34
  •   Alex Rockwell    14 年前

    我认为这是不可休息的。我认为RESTful服务不应该处理强制用户确认删除的要求。我会在用户界面中处理这个问题。

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

        3
  •  16
  •   Shay Rojansky    13 年前

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

    1. 在SQL中,delete命令接受一个参数“cascade”,该参数允许您指定还应删除从属对象。这是一个有意义的删除参数示例,但“man rm”可以提供其他参数。如果没有参数,这些情况将如何在REST/HTTP中实现?
    2. @jan,URL的路径部分标识资源似乎是一个很好的约定,而querystring则不标识资源(至少不一定)。示例很多:获取相同的资源,但格式不同,获取资源的特定字段等。如果我们将查询字符串视为资源标识符的一部分,那么在不使用HTTP内容协商等非RESTful机制(可以是非RESTful机制)的情况下,不可能有“相同资源的不同视图”的概念。有许多原因是可取的)。
        4
  •  5
  •   Jan Algermissen    14 年前

    除了亚历克斯的回答:

    注意 http://server/resource/id?force_delete=true 标识不同于 http://server/resource/id . 例如,您是否删除/customers/?状态=旧的或/客户/。