Rest service returns 404 - rest

What is the best practice in return codes if a call to a rest service executes a database query, no results are found and it returns.
Should this be a 404 or a 200 with a message stating no records?
The URL has resolved correctly and no server error has occurred just that there are no records returned.
EDIT:
Example url is:
http://localhost/app/pr_xyz/1234
Used to retrieve a list of xyz that belong to the existing user 1234. The user id 1234 has already been retrieved and is known to exist in the database. This URL (pr_xyz) is just to retrieve a list of xyz that belong to that user.
The relationship is 1 user to 0 or many xyz.
In this case the existing user has no xyz. Should this be a 404 or 200 with meaningful message.
Also I have no control over the URL.

Agree with #Satya, it should be a 200, but we can arrive at the answer by working backwards.
So, we start with the full list of HTTP status codes.. Start from the bottom.
Is it a server error? No? Then it's not a 5xx
Is it a client error? Maybe? Perhaps it's not a 4xx
It's obviously not a redirect, so it's not a 3xx.
Is it a successful call? Perhaps.
Are you returning a provisional response? No, it's not a 1xx either.
So by process of elimination, which are looking at the 2xx codes. Exactly which would be a good fit depends on the semantics of your application.
Since, this is not a DELETE call, then I probably wouldn't use 204 No Content, which is probably the only good alternative. It's not that there's no content.
There is content: "0 results found". Google doesn't show you a blank page when there are no search results.
So we arrive at 200, as well as returning a meaningful body. If you were returning raw results, then you might want to consider wrapping them in a search-results object to provide some meta-data.
Ah! So wait, what if instead of search results, you are indicating a collection of RESTful resources?
GET /items
In this case, I would still return a 200 with a body that says there are no items.
What if, you were trying to retrieve a particular resource?
GET /items/1234
In this case, yes, you want to imply that item 1234 does not exist, and you should return a 404.

Related

HTTP status code for GET request with non-existing query parameter value

Let's clarify three common scenarios when no item matches the request with a simple example:
GET /posts/{postId} and postId does not exist (status code 404, no question)
GET /posts?userId={userId} and the user with userId does not have any posts
GET /posts?userId={userId} and the user with userId does not exist itslef
I know there's no strict REST guideline for the appropriate status codes for cases 2 and 3, but it seems to be a common practice to return 200 for case 2 as it's considered a "search" request on the posts resource, so it is said that 404 might not be the best choice.
Now I wonder if there's a common practice to handle case 3. Based on a similar reasoning with case 2, 200 seems to be more relevant (and of course in the response body more info could be provided), although returning 404 to highlight the fact that userId itself does not exist is also tempting.
Any thoughts?
Ok, so first, REST doesn't say anything about what the endpoints should return. That's the HTTP spec. The HTTP spec says that if you make a request for a non-existent resource, the proper response code is 404.
Case 1 is a request for a single thing. That would return 404, as you said.
The resource being returned in case 2 is typically an envelope which contains metadata and a collection of things. It doesn't matter if the envelope has any things in it or not. So 200 is the correct response code because the envelope exists, it just so happens the envelope isn't holding any things. It would be allowable under the spec to say there's no envelope if there are no things and return 404, but that's usually not done because then the API can't send the metadata.
Case 3, then, is exactly the same thing as case 2. If expected response is an envelope, then the envelope exists whether or not the userId is valid. It would not be unreasonable to include metadata in the envelope pointing out that there is no user with userId, if the API designer thinks that information would be useful to clients.
Case 2 and Case 3 are really the same case, and should both either return 200 with an empty envelope or 404.
First piece, you need to recognize that /posts?userId={userId} identifies a resource, precisely in the same sense that /posts/{userId} or /index.html specifies a resource.
So GET /posts?userId={userId} "requests transfer of a current selected representation for the target resource."
The distinction between 200 and 404 is straight forward; if you are reporting to the consumer that "the origin server did not find a current representation for the target resource or is not willing to disclose that one exists", then you should be returning 404. If the response payload includes a current representation of the resource, then you should use the 200 status code.
404 is, of course, an response from the Client Error response class
the server SHOULD send a representation containing an explanation of the error situation, and whether it is a temporary or permanent condition.
So a way of figuring out which of these status codes to use, is to just look at the message body of the response. If it is a current representation of the resource, then you use the 200 status code. If it is a representation of a message that explains no current representation is available, then you use the 404 status code.
Of course that ducks the big question: what should the representation of the resource be in each case? Once you know that, you can work out the rest.
If you you think that an unexpected identifier indicates an error on the client (for example, a corrupted link), then it will probably improve the consumer's experience to report that as an explicit error, rather than returning a representation of an empty list.
But that's a judgment call; different API are going to have different answers, and HTTP isn't particularly biased one way or the other; HTTP just asks that you ensure that the response code and headers are appropriate for the choice that you have made.

Correct HTTP status code for possible absent entity: 200 or 204 or 404

I've searched a lot about this and have found different answers, also, my case is a little different.
The context:
I have a document A with a possible sender S
Server X (so not a browser) requests the sender from document A on Server Y, but the sender is absent.
What should server Y return:
200: with a null object (not really OK and dangerous for nullpointers on Server X)
204: a correct status I think, but this is mainly used when the endpoint does not return data in general (e.g. post, update, delete), which can be confusing
404: this should definitely the answer for .../sender/{sender_id}. But in this case we ask the sender of a document, and no sender is a correct answer...
So, what would be the best practice, or is there another approach which is better fitting for this.
Thanks in advance!
Broad rule: don't try to make status codes specific the details of your api or your domain model. Those are messages to generic components (like browsers, caches, proxies) that don't need to know anything about the specifics of your domain model and your integration protocol.
404: this should definitely the answer for .../sender/{sender_id}. But in this case we ask the sender of a document, and no sender is a correct answer...
The 4xx class of response codes indicate an error in the client request. In other words, the client asked the question wrong. 404 specifically implies that the client addressed the request to the wrong integration resource.
So it's not what you are looking for.
204: a correct status I think, but this is mainly used when the endpoint does not return data in general (e.g. post, update, delete), which can be confusing
204 has a very specific meaning - is says that the representation provided in the response is zero bytes long. "You asked me to send you the contents of this file, and I'm successfully doing so, but by the way the file is empty."
So if the representation of an absent sender is zero bytes long, aces! But if the representation is instead an empty json object
{}
Then 204 is off the table.
200 is probably your best bet.
I would suggest 404 Not Found matches best what you describe as "sender is absent"
Just in case here you can see a list of status codes: https://en.wikipedia.org/wiki/List_of_HTTP_status_codes
There are two cases here.
If you are requesting a collection eg: /users and there are no users available on the server then your service should return 200 OK with an empty list.
If you are requesting a resource by id eg: /users/id and if the user is not available then you should return 404 NOT Found as the user id that you are searching is not available on the server.
Based on your situation(assuming you are requesting for a collection of resources), I probably recommend returning 200 OK with the empty list. If you does not have control over the server then you may need to have a null check on the client side.

What should be the response of GET for multiple requested resources with some invalid ids?

what should be the response to a request to
http://localhost:8080/users/1,2,3 when the system doesn't have a user with id 3?
When all users are present I return a 200 response code with all user objects in the response body. When the user requests a single missing user I return a 404 with an error message in the body.
However, what should be the body and status code for a mix between valid and missing ids?
I assume that you want to follow REST API principles. In order to keep clear api design you should rather use query string for filtering
http://localhost:8080/users?id=1,2,3
Then you won't have such dilemmas - you can return just only users with id contained in provided value list and 200 status code (even if list is empty). This endpoint in general
http://localhost:8080/users/{id}
should be reserved for requesting single resource (user) by providing primary key.
What you are requesting there is a collection. The request essentially reads: "give me all users whose ID is in {1, 2, 3}." A subset of those users (let's say there is no user yet with the ID 3) would still be a successful operation, which is asking for a 200 (OK).
If you are overly concerned by this, there's still the possibility to redirect the client via 303 (See Other) to a resource representation without the offending elements.
If all of the IDs are invalid, things get a bit tricky. One may be tempted to simply return a 404 (Not Found), but strictly speaking that were not correct:
The 404 status code indicates that the origin server did not find a current representation for the target resource
Indeed, there is one: The empty set. From a programmatic standpoint, it may indeed be easier to just return that instead of throwing an error. This relies on clients being able to process empty sets/documents.
The RFC grants you the freedom to go either way:
[…] the origin server did not find a current representation for the target resource or is not willing to disclose that one exists.
So if you wish to hide the existence of an empty set, it's okay. It bears mentioning that a set containing nothing is not nothing itself ;)
I would recommend not to offer the method in the first place, but rather force the user of your APIto make three separate requests and return unambiguous responses (two 200s for users 1 and 2 and 404 for user 3). Additionally, the API could offer a get method that responds with all available user ids or such (depends on your system).
Alternatively, if that's not an option, I guess, you have two options:
Return 404 as soon as one user is not found, which technically is more accurate in my opinion. I mean, the request was for 1, 2 AND 3, which was not found.
Return 200 with users 1 and 2, and null, which probably is the most useful for your scenario.

HTTP 200 or 404 for empty list?

I know this is a fairly common question, but I haven't found an answer that satisfies me.
I've been using django rest framework for a while now, but this is mostly irrelevant other than the example given. Its default behaviour is to return an HTTP 200 with an empty list resource when accessing a route with an empty list of items.
E.g.: if we had a route such as /articles/ to access a list of articles but it contained no items we would get a response like the following json:
{"count":0, "next":null, "previous":null, "items": []}
Which is perfectly fine. We found the resource we were looking for at /articles/, it just happens to have no items in it.
If we access the route /articles/?page=1, we get the exact same response.
So far so good. Now we try to access /articles/?page=2, and the response code changes. Now get get a 404 as if the resource could not be found with an error message saying that the page contains no results. Which is the same case as with ?page=1...
I was perfectly ok with this behaviour, but today I started questioning this design. How is the ?page=1 case different than ?page=2 ? And what's more, how could you tell if the request was "valid" when issuing a HEAD request? Valid in the sense of containing any results.
This could be useful in cases like filtering a list checking the availability of a certain field (for example, issuing a HEAD request to /users/?username=ted).
A 200 response would clearly mean the request was understood and items were found.
A 404 would mean the request was understood, but no items were found at that location/URI (AFAIK the query parameters are also part of the URI)
In case the request could not be understood a 400 would be returned for syntactic errors, and a 422 for semantic errors.
Is this a good design? Why do most people seem to disagree with it and what drawbacks are there in it?
I would go for 200 because the resource is articles.
While querying for ted in users the same applies, users is the resource and as long it is there, a 200 is okay from my point of view.
If you would GET users/ted a 404 would be as good as a 410 (GONE) if a user named ted was there in the past (may better applies to articles than users).
Because we are ok with an empty page1, not ok with an empty page2.
This is driven by the UI consideration (page1 must exist!), nevertheless, it decides the response code.
This really boils down to the "null vs empty collection" argument. The cases for null are also cases for HTTP 404, and the cases for an empty collection are also cases for HTTP 200.
if we had a route such as /articles/ to access a list of articles but it contained no items
Assuming this is a global list of articles, i.e:
http://mywebsite/articles
then this response can never be null, and therefore should never be a 404. The global list of articles always exists, and therefore the collection is always not-null, regardless of whether it contains elements or not.
A simple example here is thinking of a SQL query. If a table exists, even if it's empty, a query will return a result (be it empty or not), so use 200. If the table itself does not exist, you get a query error, so 404.
But if the articles are contained within another resource, e.g. their author:
http://mywebsite/authors/johndoe/articles
Now we get to the part where null (and thus 404) is meaningfully possible.
If johndoe exists and has articles, you return a non-empty list
If johndoe exists and does not have articles, you return an empty list and HTTP status 200
If johndoe does not exist, then you return null and HTTP status 404
This communicates the correct response to the user. 200 reveals that the data was correctly fetched, whereas 404 reveals that the requested resource simply does not exist.
Note that this is slightly different when referring to a specific article instead of a list. When returning a specific resource (or not), instead of a list, 404 is the only correct HTTP status for a 'no item' response.
http://mywebsite/article/1
Here, you either return the article or null.
http://mywebsite/authors/johndoe/articles/1
Here, you return 404 when either author johndoe or article 1 does not exist.
200 simply means the request has succeeded. The information returned with the response is dependent on the method used in the request, for example:
GET an entity corresponding to the requested resource is sent in the response;
HEAD the entity-header fields corresponding to the requested resource are sent in the response without any message-body;
POST an entity describing or containing the result of the action;
TRACE an entity containing the request message as received by the end server.
404 - The server has not found anything matching the Request-URI - In this case I think it means we did not find the page that articles would have been listed on.
So 200 it is. - but perhaps understand what is being returned and format a message that 0 article have been returned.

Which HTTP code to use for an empty subresource in a REST API?

Let's say I've a resource articles at /articles.
These articles may have related articles, so I fetch them by GETting /articles/{id}/related.
What should I return is there is no related articles?
I can think of:
404 Not Found, maybe with an empty collection
204 No Content
200 Found with an empty collection
Any advices? (please give arguments)
By the way, it may applies to pagination. If I request page 3 of 2, then the page 3 will return an empty set, should It be a 404?
404 is not what you are looking for. It's an error condition. Your case is not an error. The client currently doesn't know if there are any related articles and wants to know. That is not an error.
204 is not appropriate either. RFC 2616 states:
The server has fulfilled the request but does not need to return an
entity-body, and might want to return updated metainformation. The
response MAY include new or updated metainformation in the form of
entity-headers, which if present SHOULD be associated with the
requested variant.
204 doesn't specify that there are no related articles. It just says that the server doesn't need to send the data.
200 with empty collection on the other hand would satisfy your need.
I wouldn't use 404 -- that would tell the client it "I'm unable to tell you whether there are any releated articles". It would be appropriate if the {id} given is not recognized at all. What you want is a positive response to tell the client, yes, good question, and here is the (empty) list of related articles.
204 is not good either, for related reasons. It specified that there is no answer, which is still different from an answer that is there but happens to be the empty list. Its description makes more sense for a POST than for a GET.
200 with an empty list is just right.
Return 200 with an empty array.