简体   繁体   English

REST、HTTP DELETE 和参数

[英]REST, HTTP DELETE and parameters

Is there anything non-RESTful about providing parameters to a HTTP DELETE request?为 HTTP DELETE 请求提供参数有什么非 RESTful 的吗?


My scenario is that I'm modelling the "Are you sure you want to delete that?"我的场景是我正在建模“您确定要删除它吗?” scenario.设想。 In some cases, the state of the resource suggests that the requested delete may be invalid.在某些情况下,资源状态表明请求的删除可能无效。 You can probably imagine some scenarios yourself where confirmation of a delete is required您可能可以自己想象一些需要确认删除的场景

The solution we have adopted is to pass a parameter to the delete request to indicate that it's ok to proceed with the delete ("?force_delete=true")我们采用的解决方案是给删除请求传递一个参数,表示可以继续删除(“?force_delete=true”)

eg例如

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

I believe that it's still restful since:我相信它仍然很安静,因为:

(a) The semantics of DELETE are not being changed - the user can still send a normal DELETE request but this may fail with 409 and the body of the response will explain why. (a) DELETE 的语义没有改变 - 用户仍然可以发送正常的 DELETE 请求,但这可能会因 409 而失败,并且响应正文将解释原因。 I say may fail because (for reasons not worth explaining) on some occasions there is no reason to prompt the user.我说可能会失败,因为(出于不值得解释的原因)在某些情况下没有理由提示用户。

(b) There's nothing in Roy's dissertation to suggest that it's against the spirit of REST - why would there be since HTTP is only one implementation of REST so why would passing HTTP parameters matter (b) Roy 的论文中没有任何内容表明它违背了 REST 的精神——为什么会这样,因为 HTTP 只是 REST 的一种实现,所以为什么传递 HTTP 参数很重要


Can someone point me at a definitive statement that nails the reason why this isn't RESTful?有人可以向我指出一个明确的声明,说明这不是 RESTful 的原因吗?

On a related question, if the user does not specify force_delete then I'm returning 409 Conflict - is that the most appropriate response code?在一个相关的问题上,如果用户没有指定 force_delete 那么我将返回409 Conflict - 这是最合适的响应代码吗?


Follow up跟进

After some further research, I think that adding parameters to the DELETE may violate several principles.经过一些进一步的研究,我认为向 DELETE 添加参数可能会违反几个原则。

The first is that the implementation possibly violates the "Uniform Interface" (see section 5.1.5 of Roy's dissertation首先是实现可能违反了“统一接口”(参见Roy 论文的第 5.1.5 节

By adding 'force_delete' we're adding an additional constraint onto the already well defined DELETE method.通过添加“force_delete”,我们在已经明确定义的 DELETE 方法上添加了一个额外的约束。 This constraint is meaningful only to us.这个约束只对我们有意义。

You could also argue that it violate the "5.1.2 Client-Server" since the confirmation dialogue is really a UI concern and again not all clients will want to confirm deletion.您也可以争辩说它违反了“5.1.2 客户端-服务器”,因为确认对话确实是一个 UI 问题,而且并非所有客户端都希望确认删除。

Suggestions anyone?任何人的建议?

No, it is not RESTful.不,它不是 RESTful。 The only reason why you should be putting a verb ( force_delete ) into the URI is if you would need to overload GET/POST methods in an environment where PUT/DELETE methods are not available.您应该将动词 ( force_delete ) 放入 URI 的唯一原因是您是否需要在 PUT/DELETE 方法不可用的环境中重载 GET/POST 方法。 Judging from your use of the DELETE method, this is not the case.从你对 DELETE 方法的使用来看,情况并非如此。

HTTP error code 409/Conflict should be used for situations where there is a conflict which prevents the RESTful service to perform the operation, but there is still a chance that the user might be able to resolve the conflict himself. HTTP 错误代码409/Conflict应用于存在阻止 RESTful 服务执行操作的冲突的情况,但用户仍有机会自行解决冲突。 A pre-deletion confirmation (where there are no real conflicts which would prevent deletion) is not a conflict per se, as nothing prevents the API from performing the requested operation.预删除确认(没有真正的冲突会阻止删除)本身不是冲突,因为没有什么可以阻止 API 执行请求的操作。

As Alex said (I don't know who downvoted him, he is correct), this should be handled in the UI, because a RESTful service as such just processes requests and should be therefore stateless (ie it must not rely on confirmations by holding any server-side information about of a request).正如亚历克斯所说(我不知道谁对他投了反对票,他是对的),这应该在 UI 中处理,因为这样的 RESTful 服务只处理请求,因此应该是无状态的(即它不能依赖于通过持有确认有关请求的任何服务器端信息)。

Two examples how to do this in UI would be to:如何在 UI 中执行此操作的两个示例是:

  • pre-HTML5 :* show a JS confirmation dialog to the user, and send the request only if the user confirms it pre-HTML5 :* 向用户显示一个 JS 确认对话框,只有在用户确认后才发送请求
  • HTML5 :* use a form with action DELETE where the form would contain only "Confirm" and "Cancel" buttons ("Confirm" would be the submit button) HTML5 :* 使用带有操作 DELETE 的表单,其中表单将仅包含“确认”和“取消”按钮(“确认”将是提交按钮)

(*) Please note that HTML versions prior to 5 do not support PUT and DELETE HTTP methods natively, however most modern browsers can do these two methods via AJAX calls. (*) 请注意,HTML 5 之前的版本本身不支持 PUT 和 DELETE HTTP 方法,但是大多数现代浏览器可以通过 AJAX 调用来执行这两种方法。 See this thread for details about cross-browser support.有关跨浏览器支持的详细信息,请参阅此线程


Update (based on additional investigation and discussions):更新(基于额外的调查和讨论):

The scenario where the service would require the force_delete=true flag to be present violates the uniform interface as defined in Roy Fielding's dissertation.服务需要存在force_delete=true标志的场景违反了 Roy Fielding 的论文中定义的统一接口 Also, as per HTTP RFC , the DELETE method may be overridden on the origin server (client), implying that this is not done on the target server (service).此外,根据HTTP RFC , DELETE 方法可能会在源服务器(客户端)上被覆盖,这意味着这不是在目标服务器(服务)上完成的。

So once the service receives a DELETE request, it should process it without needing any additional confirmation (regardless if the service actually performs the operation).因此,一旦服务收到 DELETE 请求,它应该处理它而无需任何额外的确认(无论服务是否实际执行操作)。

I think this is non-restful.我认为这是不宁静的。 I do not think the restful service should handle the requirement of forcing the user to confirm a delete.我认为 restful 服务不应该处理强制用户确认删除的要求。 I would handle this in the UI.我会在 UI 中处理这个问题。

Does specifying force_delete=true make sense if this were a program's API?如果这是程序的 API,那么指定 force_delete=true 是否有意义? If someone was writing a script to delete this resource, would you want to force them to specify force_delete=true to actually delete the resource?如果有人正在编写脚本来删除此资源,您是否要强制他们指定 force_delete=true 来实际删除该资源?

It's an old question, but here are some comments...这是一个老问题,但这里有一些评论......

  1. In SQL, the DELETE command accepts a parameter "CASCADE", which allows you to specify that dependent objects should also be deleted.在 SQL 中,DELETE 命令接受一个参数“CASCADE”,它允许您指定也应该删除依赖对象。 This is an example of a DELETE parameter that makes sense, but 'man rm' could provide others.这是一个有意义的 DELETE 参数示例,但 'man rm' 可以提供其他参数。 How would these cases possibly be implemented in REST/HTTP without a parameter?这些情况如何在没有参数的情况下在 REST/HTTP 中实现?
  2. @Jan, it seems to be a well-established convention that the path part of the URL identifies a resource, whereas the querystring does not (at least not necessarily). @Jan,URL 的路径部分标识资源似乎是一个完善的约定,而查询字符串则没有(至少不一定)。 Examples abound: getting the same resource but in a different format, getting specific fields of a resource, etc. If we consider the querystring as part of the resource identifier, it is impossible to have a concept of "different views of the same resource" without turning to non-RESTful mechanisms such as HTTP content negotiation (which can be undesirable for many reasons).例子比比皆是:获取相同资源但格式不同,获取资源的特定字段等。 如果我们将查询字符串视为资源标识符的一部分,则不可能有“同一资源的不同视图”的概念无需转向非 RESTful 机制,例如 HTTP 内容协商(出于多种原因,这可能是不可取的)。

In addition to Alex's answer:除了亚历克斯的回答:

Note that http://server/resource/id?force_delete=true identifies a different resource than http://server/resource/id.请注意,http://server/resource/id?force_delete=true 标识的资源与 http://server/resource/id 不同。 For example, it is a huge difference whether you delete /customers/?status=old or /customers/.例如,删除 /customers/?status=old 还是 /customers/ 就大不相同。

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

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