REST HTTP status code if DELETE impossible - rest

My question is quite a generic one about HTTP status code when a DELETE is impossible on the resource (but not regarding user's rights).
We have a RESTful API on a type of resource.
The DELETE method is authorized on the resource however under some conditions a resource cannot be deleted (if there are data binded to this resource).
What is the correct HTTP status code to return to the client in this situation?
Here are some of the possibilities I gathered and why it seems inappropriate in my case :
403 (Forbidden) : Seems mostly related with user's rights.
405 (Method Not Allowed) : Seems like the API is not designed to respond to this method for this type of resource.
409 (Conflict) : Seems appropriate but the client should have the possibility to resolve the conflict with the API but that's not the case here.
Update : The data binding that prevents the resource to be deleted cannot be changed via the REST API. However the resource can be "freed" via other way as the database from which the data comes from is also accessed by other apps that may change the state of a resource (an SQL DELETE in the DB can always do that).

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.

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.

Related

Write once semantics for REST interface

We have a REST interface that allows clients to create a Product resource. The Product can be associated with different kind of metadata.
/Product/{id}/metadata/{md_type}
The team wants a particular type of metadata to be written only ONCE. Subsequent updates should be rejected.
Currently, a PUT request is used to create the metadata. The metadata is not assigned an ID. It is immutable. The PUT request is rejected if the metadata already exist.
Using PUT feels like a violation of REST semantics. What is the most RESTful way to handle the situation?
Using PUT feels like a violation of REST semantics. What is the most RESTful way to handle the situation?
Using PUT is perfect here.
The simplest answer is that you are missing the fact that this is a Conditional Request; if the client were to send its request with an If-None-Match header, then all of the generic handling of conditional requests would "just work", with the server returning a 412 Precondition Failed if the resource already has a representation.
If the client doesn't include the If-None-Match header, then I don't think 412 is appropriate. Perhaps 405 Method Not Allowed, or 409 Conflict; 403 Forbidden is on point but may confuse humans who think that must refer to a credentials problem.
Rejecting updates on subsequent PUTs violates the principal of least surprise for RESTful interfaces.
No, it doesn't. Because PUT defines and constrains the semantics of the request, it doesn't obligate the server to fulfill the request.

HTTP Status Code when the Parent Resource is not longer live

In our Organization, the items in our inventory are called stocks. Each stock has a sortScore associated with it. An internal API is exposed to another team in the organization to update the sortScore of the stock.
PUT /api/stock/{stockid}/sortscore
This request updates the sortScore of the stock. It may happen that the stock is no more live(it is sold), but for some reason, the internal API for updating the sortScore is still hit by another team.
According to me, here the resource is sortScore and the parent resource is the stock, which isn't live anymore(It used to be live at some point of time). Even though the stock is no more live, we still keep a record of it somewhere in our Database.
Some of us are having arguement about the HTTP Status code we are sending when the stock is not live anymore. Since the resource is not available at the intended Resource Identifier(URL), we are sending NOT FOUND. But some of our colleagues are saying that since the stock used to be live at some point of time, the Status Code should be of 2xx series with the message that This stock is not live anymore.
Now I am here to know what the people from stackoverflow thinks about what the correct answer should be?
So an important thing to understand about REST is that the concepts of "parent resource" and "child resource" don't really exist.
As far as REST, and HTTP, is concerned; /a/b/c doesn't necessarily have anything to do with /a/b or /a/b/c/d. Each resource is its own thing, with its own representation(s).
So you should be thinking about
PUT /api/stock/{stockid}/sortscore
In isolation.
Since you aren't allowing the clients to change the resource, using 2xx status code is not the right idea. A 2xx status code would not only indicate that the request had been successful, but would also encourage consumers to flush their caches and so on.
404 Not Found isn't quite the right idea, since a PUT should create a resource if there isn't one present already.
The PUT method requests that the state of the target resource be created or replaced with the state defined by the representation enclosed in the request message payload
It sounds to me as though "it's not live any more" means that consumers are no longer allowed to modify the state of the resource. That in turn suggests that the status code you want is 405 Method Not Allowed
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.
A common status code for this is 409 Conflict. The idea of 409 Conflict is that even though everything is fine with your request, the current state of the server prevents it from being successful.
The current state in your case is a different resource not existing anymore. This is in conflict with the PUT request you are doing.

What's an appropriate HTTP status code to return by a REST API service for an expired entity?

Let's say we have an online shop and receive a valid request of updating some order.
The request is valid by itself, but let's say that the order has an expiration time, and it has already expired, so this request is unprocessable in fact.
I doubt if it is a kind of validation error or not. Because, as I stated above, the request itself is valid; and a request sender might not know that order has already expired.
What's an appropriate HTTP status code to return by a REST API service for such a situation?
Warning: Due to the general requirements for the product, it should be some of 4XX error codes!
UPD: More information: this putative "order" still exists, even being expired. It is possible to retrieve it, but it is not possible to operate it anymore. That's why the code 404 (for example) is not appropriate.
My own version:
I think that for such situation the 410 status code is most appropriate:
The 410 response is primarily intended to assist the task of web
maintenance by notifying the recipient that the resource is
intentionally unavailable and that the server owners desire that
remote links to that resource be removed. Such an event is common
for limited-time, promotional services and for resources belonging to
individuals no longer associated with the origin server's site. It
is not necessary to mark all permanently unavailable resources as
"gone" or to keep the mark for any length of time -- that is left to
the discretion of the server owner.
https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html:
The requested resource is no longer available at the server and no
forwarding address is known. This condition is expected to be
considered permanent. Clients with link editing capabilities SHOULD
delete references to the Request-URI after user approval. If the
server does not know, or has no facility to determine, whether or not
the condition is permanent, the status code 404 (Not Found) SHOULD be
used instead. This response is cacheable unless indicated otherwise
I'll say that 400 fits better than 410.
IMO 410 (Gone) doesn't fit because the resource is not gone. It's still there, simply in kind of a final (in this case expired) state.
400 means BadRequest. Per my interpretation, trying to UPDATE something, that is not updatable (trying to update expired item) is a BadRequest.
I believe, that 400 is not only for badly formatted requests, but also for requests that does not meet internal business logic validation (in this case, not updating an expired item, is an internal business logic).
Use 410 Gone.
The target resource is no longer available at the origin server and that this condition is likely to be permanent.
I would choose one of these:
400 - Bad request
410 - Gone
from : https://en.wikipedia.org/wiki/List_of_HTTP_status_codes

Http REST status code for Resource Available and Not Available

I am using HTTP HEAD request for checking is a userlogin name is available or not. Now I am returning a 200 OK response if the user login name is available, What do I return if login is not available? Should it be 409 or 403 or 410 (Gone).
I believe that 409 makes the most sense.
The request could not be completed due to a conflict (username already taken).
This code is only allowed in situations where it is expected that the user might be able to resolve the conflict and resubmit the request.
Your response body SHOULD include enough information for the user to understand the username is already taken.
Edit
The 410 Gone response should only be used if requested resource is no longer available at the server and no forwarding address is known. These are for situations where the request-URI is not available temporarily. Some suggest to just use 404 if you think the URI will be down for long periods.
The 403 indicates a fundamental access problem. It is more difficult to resolve because the HTTP protocol allows the Web server to give this response without providing any reason at all. This is equivalent to a blanket 'NO' by the Web server - with no further discussion allowed.

REST API best HTTP Status response for illegal operation

I'm creating a REST API in PHP.
When the client may try to perform an action, which is unavailable, for example, it tries to change a property of the resource which is not passable: for example, tries to change the value of the "country" property to "Julius Caesar":
What HTTP status code should I send back with the response? I'm speculating between 403 and 409.
I don't know if 403 Forbidden is only related to user permissions or can I use for this purpose?
In what situation should I use 409 Conflict?
To summarize what is the proper HTTP response status to an illegal operation?
I think you should use a 403 Forbidden here.
From the HTTP specification:
The server understood the request, but is refusing to fulfill it.
Authorization will not help and the request SHOULD NOT be repeated. (...)
As you are refusing to change the value of "country", this is the status code you want to return. The client is not authorized to change the resource's country.
409 Conflict is not appropriate in this case. The 409 status is to be used when for instance somebody sends a request to update a resource, but their version of the resource is outdated because the resource has been modified in the meantime. In other words, there is a conflict between the client's data and the data on the server. This has nothing to do with allowing certain properties of the resource to be changed.
The request could not be completed due to a conflict with the current
state of the resource. This code is only allowed in situations where
it is expected that the user might be able to resolve the conflict and
resubmit the request. The response body SHOULD include enough
information for the user to recognize the source of the conflict.
Ideally, the response entity would include enough information for the
user or user agent to fix the problem; however, that might not be
possible and is not required.
Conflicts are most likely to occur in response to a PUT request. For
example, if versioning were being used and the entity being PUT
included changes to a resource which conflict with those made by an
earlier (third-party) request, the server might use the 409 response
to indicate that it can't complete the request. In this case, the
response entity would likely contain a list of the differences between
the two versions in a format defined by the response Content-Type.
(emphasis mine)
In this situation, I usually opt for a 400 Bad Request. I'm not sure if a more specific 400 range status code would fit better, however I would not use 403. For me, a 403 is security related, and should not be used for request payload validation errors.
As for 409 Conflict, I usually use this if the request is valid, but the state change is somehow illegal. However, I have seen it used in other contexts as well.
In the end, as long as you are consistent across your API (and document the meaning of the return status codes), you have some flexibility to decide how you want to express the error.