Would a 404 be acceptable for a DELETE method being called on a non-existent URL? - rest

I am pretty new to the RESTful world, and at the moment I'm debating whether when calling a delete method on a URL that doesn't exist, whether a 404 Resource Not Found should be returned. At the moment, the code returns a 200 OK code, but this doesn't inform a user that what they wanted to do wasn't possible.
I have looked online and on here, and a lot of people have divided opinions on the matter, with HTTP having no standards on return codes.
(I'm thinking in a scenario where someone wants to delete something but through something like a typo, deletes an invalid resource but through there being no error code returned, isn't informed that the delete was unsuccessful, and doesn't realise the mistake.)

I would return the 404 and allow the front-end developer to decide how to handle the situation. As a front-end developer if my user attempted to delete a resource that did not exist, I would like to handle that situation. It could be that the resource was deleted by another user between the time that I found the resource and the present. On the other hand it could be that there was a typo like you said.
But regardless, I would like to know if the user is attempting to delete a resource that no longer exists so that I may handle the situation appropriately.
But this situation depends on the type of application you are constructing. For example, you may want to return a 410 in the case that another user deleted the resource in the last 5 minutes, then return a 404 for all non-existent URLs. But once again, I would only expect a 200 to be returned if something was actually deleted.
SharePoint REST follows this pattern.

Related

When route was not implemented on server, should it return 404 or 501?

I always returned 404 when some route has not been implemented and no resource exists. For example, if I have a API that returns people at /api/people, if I try to get a object on /api/animals, I'm going to return 404.
A cowork of mine said 404 is only for not found resources, like if I try to get /api/people/100 but there's no people with ID 100. For the /api/animals he would return 501.
For me, the meaning for 501 is when I have a route that won't support one of the methods, like if I can get /api/people/3 but can't delete it.
I decided to look at the specification:
The 404 (Not Found) status code indicates that the origin server did not find a current representation for the target resource or is not willing to disclose that one exists. A 404 status code does not indicate whether this lack of representation is temporary or permanent; the 410 (Gone) status code is preferred over 404 if the origin server knows, presumably through some configurable means, that the condition is likely to be permanent.
The 501 (Not Implemented) status code indicates that the server does not support the functionality required to fulfill the request. This is the appropriate response when the server does not recognize the request method and is not capable of supporting it for any resource.
For me it seems the specification is a little ambiguous. At the same time it's arguable that /api/animals has not been found by the origin server (404), it's also true that the origin server did not implement the method to fullfill the request (501).
In this case, what is the most proper status code to return?
If you went into a bookshop and asked the person behind the counter to get "The best 100 cakes" from the shelf and the book wasn't in stock, they would return and politely say "I'm sorry I can't find that book". Automate that in a book finding system and it would return 404.
The manager of the bookshop wouldn't appear, instead of the person looking for your book and tell you "I'm afraid we don't support looking for that particular book as our staff can only look for books we have" (501).
If you went into a bookshop and asked the person behind the counter to get you a lawnmower they would politely reply "I'm sorry I don't know how to do that". That would be a 501. If you asked the person in the bookshop to get rid of a book that you'd just seen on the shelf, that would be a 501 too.
A 404 is, "ok, I know how to get that but it isn't there". A 501 is a "WTF! What do you think this place is?".
Whether the 404 is permanent depends on what is answering the question. If it's a REST API, it could return JSON status saying something like the book is out of stock but is on order, with a likely due date.
The real reason it's a 501 when trying to get the book person to chuck out a book they have on a shelf is, if they just said 404, you'd just say, "there it is there!". They'd need to state the real reason they couldn't do that. They have no business policy that allows them to chuck out random books without buying them.
So, technically, the apparatus is there, they can walk up to the book, grab it but stop with a 501 as the policy hasn't been implemented.
"ok, I know how to turn a REST url into functionality, that's how I know what functionality you want, but hey, we only deal with people here, 501".

Use of HTTP 204 vs 200 vs 404 to safely signal that a resource doesn't exist

In my REST API I have the normal CRUD endpoints for some resources.
If I do a GET /items/42 and there is no such item, the normal behaviour would be to return a 404 NOT FOUND.
However, one scenario concerns me. In this scenario, a client needs to check if a resource (which is implicitly idenfitied by a token) exists, and if not, create it. So, the client would try to retrieve the resource, and if a 404 is received the client application would display the UI necessary for creating the item, and then proceed to POSTing the new resource. In a way, this is a special kind of resource, because since its ID is derived from other parameters, it's known even before creation. As an example, consider a user sign-up procedure; the client would ask "Do I exist? If no -> register me".
My concern is really whether I ever need to worry about "spurious" 404:s? Considering a server is usually surrounded by API gateways, reverse proxies and such, is there any risk that a 404 NOT FOUND could be produced by a surrounding entity due to some temporary error not related to the REST server itself? If so, it could trick the client into believing that the item is not created yet, and that it should now be created. Even if the resulting POST request to create the item would fail because the item already exists, this isn't very nice because the user may have entered data etc for no reason.
Is this a problem to take into account or just overly paranoid? I guess if clients can't trust a 404 to be idempotent (until the resource is created, of course), many other issues arise. Is there any actual situation where an API gateway or similar would report a 404 on its own?
If this is a valid scenario, do I need a "safer", more explicit response saying that the request definetely succeeded but the resource wasn't found, such as responding with a 200 OK with an empty JSON body or a {isRegistered: false}, a 204 NO CONTENT, or similar? This opens up for other strange things - if a request for a resource that doesn't exist would respond with a 200 accompanied by an empty body, perhaps creation of the item would be a PUT rather than a POST, etc? This seems like a can of worms... It all boils down to "Does a 404 guarantee that the given resource doesn't exist?".
404 is pretty unambiguous : the resource wasn't found and it's a client error (4xx). Normally, server-side errors (5xx) can't interfere and create spurious 404's here.
As an alternative, if the resource to be created is linked to another resource in a unique way, you could use OPTIONS to ask the server if it already exists.
For instance :
OPTIONS /visitors/7883930/user-account
=> Allow: POST,OPTIONS (doesn't exist)
=> Allow: GET,OPTIONS (exists)
The key here is to have a URI that allows accessing the resource without knowing its ID. It is not always possible though.

REST delete in reality update

i'm currently trying to build simple REST api with one endpoint or users looking like this:
GET /users - get all
GET /users/{id} - get one
POST /users - create
PUT /users/{id} - update
DELETE /users/{id} - delete
The problem is with DELETE, because DELETE in reality only UPDATE user resource with status REMOVED. Is it ok? And which status should I return? I'm currently returning 202 Accepted, as i believe that saying "Resource is accepted to be removed" is ok, but maybe there should be just 200 OK
When designing an API, you should always consider what the giving action means for the user of the API.
The user would not really want to know what happens behind the scenes, but only want a clean and understandable set of actions.
So for you delete action, you should consider, "will this delete the item, from the users perspective?"
Responding with status code 200 most often fine, but remember to send some content with it to support it.
Using many different status code for success does not really give value, so be careful.
RestApiTutorial says this.
DELETE is pretty easy to understand. It is used to delete a
resource identified by a URI.
On successful deletion, return HTTP status 200 (OK) along with a
response body, perhaps the representation of the deleted item (often
demands too much bandwidth), or a wrapped response (see Return Values
below). Either that or return HTTP status 204 (NO CONTENT) with no
response body. In other words, a 204 status with no body, or the
JSEND-style response and HTTP status 200 are the recommended
responses.
But you can use It for your prupose, if It do your Api logic easier to understand to the user.
I Hope It helps you.
The question that you have to ask yourself is:
Does the resource after the DELETE will still be available to the client?
If the answer is yes then I would suggest to use a PATCH you can even use the RFC6902 for that.
If the answer is no then DELETE is fine.
But since you have mention that the idea is to flag the user with a status delete I guess you have the intention to query all deleted user at some point or do something useful with it. Witch seems to be a client [admin] use case so PATCH sounds appropriate.
Regarding the status for DELETE. Some people may prefer to use the 204 No content since you are expecting the resource to be removed.

REST and validation of one field

I'm no expert in this so please tell me if I'm way off :)
I'm trying to define a REST service that handles accounts.
/Accounts/32 (GET to fetch one)
/Accounts (GET to fetch all)
And so on...
However, in the sign up process, before an account is created, I would like to verify a couple of fields, like E-mail and ssn, async before the account is created.
How should I go about doing so? I just want to know if they exist in a combination but I shouldn't get a resource back since it's none of my business. :)
Is it valid to do something like this?
/Accounts?ssn=123&email=a#email.com&operation=verifyexistance
Thanks
// Johan
Interesting question, for me I would prefer to do the following:
HEAD /accounts?ssn=123&email=a#email.com
if response status code is 200 then the resource exist on the server
if response status code is 404 then the resource not available and you can continue with registration
The HEAD method is identical to GET except that the server MUST NOT return a message-body in the response.
I like Anas Salman's answer, which suggests the use of HEAD. That's the ideal method.
But I also think that GET is perfectly fine. You are requesting to get information about the resource (the /accounts collection).
GET /accounts?ssn=123&email=a#example.org
When /accounts sees a request in this format (a GET request with an SSN and email address provided), it has enough information to know to respond appropriately with an affirmative or negative.
The addition of an "operation" verb in the query string is the only unRESTFUL part of your example.

Returning REST 400-Bad Request with additional information

Hey,
I have a REST based server, and in some cases I want to return a failure code (400 for example), BUT, I wish to add additional URL.
Something like - "failure, but here's what you can do now.."
Is there any good convention to do so?
Is it even a good idea to return error with additional information?
Thanks,
Udi
It is always a good idea to return additional information in an error message. The HTTP spec itself says so: "Except when responding to a HEAD request, the server SHOULD include an entity containing an explanation of the error situation, and whether it is a temporary or permanent condition. These status codes are applicable to any request method. User agents SHOULD display any included entity to the user."
One thing to watch out for: some versions of Internet Explorer will not show the user your additional error information if it is not a certain number of bytes. Make sure your response entities for error messages are at least 512 bytes to be sure.