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

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.

Related

Is a 404 http code appropriate when a successful REST query gives 0 results?

We had a bit of a heated debate at work this week regarding the proper use of HTTP error code 404. I feel that it is being used inappropriately in this situation, and they insist that "this is how it is everywhere".
Here's the scenario:
We have a REST API endpoint with a static URI like "https://server.domain.com/restapi/getnode" that accepts a json body during a POST operation to see if a server exists within the database. There is 1 server allowed per query.
The way it is designed, if the server exists, it returns http code 200 with the body of the message being the details of the server within the database. If it doesn't exist, then they return a 404 code with the message "server x is not found in database y".
I feel that this is incorrect because according to the standards from W3C 4xx codes are for client-related issues, and 404 is specifically if the server can not server up that specific URI. Further, this is not really an error, we would not only expect the occasional negative/empty response as part of the normal business, but that is expected to be the state on the majority of the calls.
Their response to this is that according to sources such as AWS REST Standards and ServiceNow REST Standards that 404 is appropriate because the query didn't find the server, therefore it couldn't find the resource (To which I feel that they are misinterpreting the term "resource").
So, who is correct here? Or is this more of a gray area than I think it is?
The relevant part of the specification here is Client Error 4xx.
Except when responding to a HEAD request, the server SHOULD send a representation containing an explanation of the error situation, and whether it is a temporary or permanent condition.
User agents SHOULD display any included representation to the user.
In other words, the status code is meta data that indicates to general-purpose components that the payload of the response is an explanation of the error, and not a representation of the resource.
If what you are actually doing is returning a representation of the resource which is at this moment an empty list, then you should be using a Successful code, not a Client Error code.
For example, if we have a resource that lists women who have been sworn into the office of President of the United States, the expression of that resource, as of 2019-09-25, would be an empty list. So a standard HTTP response would look like
200 OK
Content-Type: application/json
[]
On the other hand, this response says something completely different
404 Not Found
Content-Type: application/json
[]
What this says is that there was no current representation of the requested resource, and the representation of the explanation of the problem is an empty list, so please show an empty list to the user so that they know what to do.
This is a neverending debate with no useful outcome. See for example How to design RESTful search/filtering?, Do web applications use HTTP as a transport layer, or do they count as an integral part of the HTTP server? (disclaimer: my question), and thousands of other questions on the Stack Exchange network and thousands of blogs like "which status code to pick for REST scenario XYZ".
The fact that you're using POST for a request with GET semantics, means you're already not properly applying REST. POST is used to create resources, not to find existing resources. If you have a "servers" resource collection, then you're dealing with "server" resources.
If you want to have a "find-server" endpoint, and you want to use POST to "create" a "find-server resource result", which you can then issue a GET request to to obtain your search results, you're a masochist who tries to shoehorn an application into a design philosophy that doesn't fit the problem domain.
So just be pragmatic. Does the endpoint exist? Yes, so 404 is not applicable. Return a 200 (the resource exists, the request is correct) with an body indicating no results were found, or a 204 ("no content") without a body.

What is the correct status code after testing if an e-mail address exists in the database or not?

We are using a specific endpoint on our API to test if an e-mail address is already registered in our database. When it's not, what would be the right status code to return to the client ?
We cannot take a decision between 404, 204 and 200. There are a couple of articles over the net but all state pros and cons but it's not very clear.
200 says that the request was successful
204 says that the request was successful AND that the message body included in the response is 0 bytes long.
404 says that there is no current implementation associated with the requested resource
Which of these is correct really depends on your resource design.
Consider a database query with a where clause -- if there are no matching rows, then you get SUCCESS, with an empty result set. So the analogous thing in a HTTP response would be a 2xx status code, and a body that describes an empty set.
If you were using a JSON List as your representation of the set, then the representation would be two bytes long [], and a 200 status code would be appropriate. If you were using a json lines representation, with each record on its own line, then with no records you would have no lines, therefore a 0 byte representation and 204 would be a good choice.
What about a case where we have a simple web page, that tells you if the email address is registered or not? If it's registered, the server responds with a 200 message and a html document that tells you about the registration. If it isn't registered, then you get an html message telling you that the email address isn't registered... and a 200, because we were able to find the current representation of the resource.
And 404? 404 indicates to the client that there appears to have been a spelling error in the target-uri of the http request -- that there isn't even nothing to find.
It may help to understand that status codes are metadata about the HTTP response, which is to say that they are part of the application domain of transferring documents over a network, not about the business domain. They are there so that generic components, like caches, can do interesting things without needing to know any specifics about the domain in question.
Our web API is a facade to make our domain model look like a boring document store.

What is the proper response status for a REST API GET returning no content?

I have an endpoint like so:
GET /api/customer/primary
If a primary customer exists, I return something like
{
name: "customerName"
}
But what if I send a GET and a primary customer doesn't exist?
Is it better to send a 200 OK with an empty JSON {}
Or is better to only send a 204 No Content?
404 is the appropriate status code for this. You're trying to represent a 'primary customer' as a resource, but in some cases this relationship doesn't exists. This situation is pretty clear, it should be a 404 for GET requests.
This is a perfectly acceptable way to communicate this. A 404 might signal a client that the resource doesn't exist yet, and perhaps that it can be created with PUT.
204 No Content has a specific meaning, and doesn't make that much sense for your case. 204 is not just meant to signal there's not going to be response body (Content-Length: 0 can do that), but it has a more specific application for hypermedia applications. Specifically, it signals that when a user performs an action that results in the 204, the view shouldn't refresh. This makes sense for for example an "Update" operation where a user can occasionally save their progress while working on a document. Contrast to 205 Reset Content, which signals that the 'view' should reset so (perhaps) a new document can be created from scratch.
Most applications don't go this far. Frankly, I haven't seen a single one. Given that, returning 200 with Content-Length: 0 or 204 No Content is an almost completely irrelevant discussion. The HTTP specification certainly doesn't forbid 200 OK with Content-Length: 0.
That was a bit of a tangent. To conclude, 404 signals this 'thing' doesn't exist, and that's appropriate here. There's no multiple interpretations. There's the people who wrote the specifications, those who read them well and on the other side of the discussion the people who are wrong.
But what if I send a GET and a primary customer doesn't exist?
Is it better to send a 200 OK with an empty JSON {}
Or is better to only send a 204 No Content?
If I'm interpreting your question correctly, you aren't really asking about status codes, but rather what kind of schema should you be using to manage the different cases in your API.
For cases like REST, where the two ends of the conversation are not necessarily controlled by the same organization and same release cycle, you may need to consider that one side of the conversation is using a more recent schema version than the other.
So how is that going to be possible? The best treatments I have seen focus on designing schema for extension - new fields are optional, and have documented semantics for how they should be understood if a field is absent.
From that perspective
{}
Doesn't look like a representation of a missing object - it looks like a representation of an object with default values for all of the optional fields.
It might be that what you want is something like Maybe or Option - where instead of promising to send back an object or not, you are promising to send back a collection of zero or one object. Collections I would normally expected to be represented in JSON as a array, rather than an object.
[]
Now, with that idea in pocket, I think it's reasonable to decide that you are returning a representation of a Maybe, where the representation of None is zero bytes long, and the representation of Some(object) is the JSON representation of the object.
So in that design 204 when returning None makes a lot of sense, and you can promise that if a successful response returns a body, that there is really something there.
There's a trade off here - the list form allows consumers to always parse the data, but they have to do that even when a None is sent. On the other hand, using the empty representation for None saves a parse, but requires that the consumer be paying attention to the content length.
So, looking back to your two proposals, I would expect that using 204 is going to be the more successful long term approach.
Another possibility would be to return the null primitive type when you want to express that there is no object available. This would go with a 200 response, because the content length would be four bytes long.
null
HTTP 404 status's text ("Not Found") is the closest to the situation, But:
The first digit of the Status-Code defines the class of response. The
last two digits do not have any categorization role. There are 5
values for the first digit:
1xx: Informational - Request received, continuing process
2xx: Success - The action was successfully received,
understood, and accepted
3xx: Redirection - Further action must be taken in order to
complete the request
4xx: Client Error - The request contains bad syntax or cannot
be fulfilled
5xx: Server Error - The server failed to fulfill an apparently
valid request
(reference)
In practice, 4xx recognized as an error and it is likely some alerts will rise from network / security / logging infrastructure
204 semantic indicate that the server has successfully fulfilled a request and there is no additional content to send - not exactly what happening.
A common use case is to return 204 as a result of a PUT request, updating the resource.
Therefore I would recommend using either:
HTTP 200 with an empty object / array
like you suggested.
HTTP 200 returning a null object, e.g.:
"none" (valid JSON)
or
{
"name": "NO_PRIMARY_CUSTOMER"
}
(implementation of such a null object depends on your specific system behavior with the returned data)
Custom HTTP 2xx code with an empty result
Less common, but still workable alternative is to return a custom HTTP code within the 2xx range (e.g. HTTP 230) with an empty result.
This option should be used with extra caution or even avoided if the API is exposed to a wide audience that may use unknown tools to access / monitor the API.

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.

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.