如果不可能删除,休息 HTTP状态码

我的问题是一个相当普通的 HTTP状态码,当一个 删除是不可能的资源(但不涉及用户的权利)。

我们在一种资源类型上有一个 RESTful API。

删除方法在资源上被授权,但是在某些条件下不能删除资源(如果有数据绑定到此资源)。

在这种情况下返还给客户的正确 HTTP状态码是什么?

下面是我收集到的一些可能性,以及为什么在我的情况下它似乎不合适:

  • 403 (禁止) : 似乎主要与用户权利有关。
  • 405 (方法不允许) : 看起来 API 的设计并不是为了响应这种类型的资源的这种方法。
  • 409 (冲突) : 似乎合适,但客户端应该有可能解决与 API 的冲突,但这里的情况并非如此。

更新: 不能通过 REST API 更改阻止删除资源的数据绑定。然而,资源可以通过其他方式“释放”,因为数据来源的数据库也可以被其他可能改变资源状态的应用程序访问(数据库中的 SQL DELETE 总是可以做到这一点)。

32701 次浏览

A 409 Conflict response is definitely wrong if the client can't resolve the conflict and delete the request later. That is, unless the resource has state tracking whether it can be deleted or not, 409 Conflict is not a good fit.

A 403 Forbidden doesn't necessarily mean not authorized:

However, a request might be forbidden for reasons unrelated to the credentials.
   -- RFC 7231

The implication is usually there, though. You can use this code, but it may cause some confusion. It'll be especially tricky if the method actually requires authorization also - you'll need a code or something in the response indicating whether the failure was related to authorization or the resource being non-deletable.

I think that 405 Method Not Allowed is the correct way to go.

The 405 (Method Not Allowed) status code indicates that the method received in the request-line is known by the origin server but not supported by the target resource.
   -- RFC 7231

The method DELETE is not supported for this resource. That sounds exactly like what you're describing. The HTTP spec doesn't really have a concept of a type of resource - just a resource. It happens that people group individual resources under the same endpoint for sanity, but that's just a convenience for developers and users. As far as the HTTP spec is concerned, /widgets/12 and /widgets/15 and /widgets/3453 are three different resources. The fact that the same object represents all three of those resources on the server is completely irrelevant. I think that's the "type" you're thinking of, but to HTTP that's just an implementation detail.

I'd say 409 is the most appropriate, given it's wording in the RFC:

The 409 (Conflict) status code indicates that the request could not be completed due to a conflict with the current state of the target resource. This code is used in situations where the user might be able to resolve the conflict and resubmit the request. The server SHOULD generate a payload that includes enough information for a user to recognize the source of the conflict.

(emphasis mine)

Based on my understanding of the description in the question, the reason for DELETE not being allowed is exactly a conflict with the current state of the target resource. As indicated in the RFC, the response payload can give an indication of the reason and, optionally, the user might be able to resolve it. I don't see anything in the spec that makes 409 inappropriate just because the API doesn't offer a conflict resolution possibility.