简体   繁体   English

删除不存在的资源是否应该在 RESTful Rails 中导致 404?

[英]Should deleting a non-existent resource result in a 404 in RESTful Rails?

In a brand new Rails application with a scaffolded RESTful model, the generated delete code looks like this:在带有脚手架 RESTful model 的全新 Rails 应用程序中,生成的删除代码如下所示:

class BeersController < ApplicationController
  # DELETE /beers/1
  # DELETE /beers/1.xml
  def destroy
    @beer = Beer.find(params[:id])
    @beer.destroy

    respond_to do |format|
      format.html { redirect_to(beers_url) }
      format.xml  { head :ok }
    end
  end
end

If a user tries to delete the same Beer twice (maybe a quick double-click, or actions in two different browser tabs) they will get a RecordNotFound error resulting in a 404 page.如果用户尝试两次删除同一个 Beer(可能是快速双击,或在两个不同的浏览器选项卡中执行操作),他们将收到 RecordNotFound 错误,从而导致 404 页面。 This is a pretty unfriendly experience;这是一种非常不友好的体验; it seems like it would be better to complete the redirect back to beers_url regardless, possibly with a flash error, since there isn't really anything the user can do about the second delete failing.似乎最好完成重定向回beers_url无论如何,可能会出现flash错误,因为对于第二次删除失败,用户实际上无能为力。

An alternative approach is to act like the delete succeeded anyway with something like this:另一种方法是通过以下方式表现得像删除成功一样:

def destroy
  @beer = Beer.find_by_id(params[:id])
  destroyed = @beer.try(:destroy)        

  respond_to do |format|
    format.html { redirect_to(beers_url) }
    format.xml  { destroyed ? head(:ok) : head(:not_found) }
  end
end

I can understand the desire for a hard 404 error in the API use-case, but it's harder for me to justify for a web application.我可以理解在 API 用例中出现硬 404 错误的愿望,但我更难证明 web 应用程序的合理性。 Can anyone provide a good reason why we should throw a scary error at the user in the name of RESTfulness?谁能提供一个很好的理由,说明为什么我们应该以 RESTfulness 的名义向用户抛出一个可怕的错误?

(This question isn't particular to Rails, but I don't know how other frameworks handle this case out of the box). (这个问题不是 Rails 特有的,但我不知道其他框架如何开箱即用地处理这种情况)。

UPDATE : It turns out I was wrong: https://stackoverflow.com/a/24713946/14731 更新 :事实证明我错了: https//stackoverflow.com/a/24713946/14731


Previous answer : HTTP DELETE is an idempotent operation. 上一个答案HTTP DELETE是一个幂等操作。 Invoking it multiple times consecutively must result in the same behavior as the first. 连续多次调用它必须导致与第一次相同的行为。 Meaning: you shouldn't return HTTP 404 . 含义: 您不应该返回HTTP 404

I don't think you should ever throw the error at the user for the sake of holding up some standard - especially if this is a consumer facing app (as opposed to B2B). 我认为你不应该为了保持一些标准而向用户抛出错误 - 特别是如果这是一个面向消费者的应用程序(而不是B2B)。 But you also shouldn't make your api change its status code just for this one situation. 但是你也不应该只为这种情况让你的api改变它的状态代码。 The resource doesn't exist anymore; 资源不再存在; so a 404 is a proper response. 所以404是一个恰当的回应。

I think there is a path of least (or lessor - is that even a word???) resistance here. 我认为这里有一条最小的路径(或者更少的 - 甚至是一个词)。 I haven't explored ruby yet so I can't provide any usable implementation; 我还没有探索ruby,所以我无法提供任何可用的实现; but I'm somewhat experienced with web apps using html/css/js. 但我对使用html / css / js的网络应用程序有一定的经验。

If there is some legitimate problem with users clicking a button twice; 如果用户点击两次按钮存在一些合法问题; why not set up the button so that it disables when the request is submitted, and re-enables once the conditions are proper (request has come back)? 为什么不设置按钮以便在提交请求时禁用它,并在条件正确后重新启用(请求已经返回)? In other words, avoid the if(this very specific situation) logic by making it impossible to get into the situation you're seeing. 换句话说,通过使得无法进入你所看到的情况来避免if(这种非常具体的情况)逻辑。 I'm assuming ruby has something specifically for handling requests and adding function handlers for different status codes; 我假设ruby专门用于处理请求和为不同的状态代码添加函数处理程序; or at least non-200 status codes. 或至少非200状态代码。

Rails scaffold code is a suggestion at best. Rails脚手架代码充其量只是一个建议。 Your instinct to make the error message more user friendly is a good one. 您使错误消息更加用户友好的直觉是一个很好的直觉。

There's no reason you can't return a nicely formatted 404 page with your response. 没有理由你不能用你的回复返回格式良好的404页面。 The status code could be the same, just the rendering is more user friendly than your typical 404 page. 状态代码可以是相同的,只是渲染比典型的404页面更加用户友好。 You could even return the "redirected" page in the response body. 您甚至可以在响应正文中返回“重定向”页面。 One possible problem with this is browser support. 一个可能的问题是浏览器支持。 It's been quite a few years but I seem to recall IE (6?) completely disregarding response body content when receiving a 404. You'll have to experiment to see what works best for you. 这已经有好几年了,但我似乎回想起IE(6?)在收到404时完全无视响应主体内容。你将不得不尝试看看哪种方式最适合你。

I was thinking about the security aspect of the response provided to the client.我在考虑提供给客户的响应的安全方面。 If you get 204 you understand that the resource did exist but on 404 you can tell there is no such resource.如果您得到 204,您就知道该资源确实存在,但在 404 上您可以判断没有这样的资源。

Not sure though how this can be exploited.不确定如何利用它。

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

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