I am calling a REST API for a list of resources and getting the json response as below if atleast one resource is there.
{
"value": [
"res1_id",
"res2_id",
"res3_id"
]
}
and the HTTP response code is 200.
But when no resource is there the server is returning HTTP response code as 404.
My doubt it why it is designed that way(it is an enterprise product).
I was expecting a empty list as below and HTTP response code 200:
{
"value": []
}
I am not able to understand what design decision has been taken into consideration to return 404 instead of an empty json.
Please help me to understand the reasoning behind it.
What I am reading here is that you have a 'collection' resource. This collection resource contains a list of sub-resources.
There's two possible interpretations for this case.
The collection resource is 0-length.
The collection resource doesn't exist.
Most API's will treat a 0-length collection as a resource that still exists, with a 200 OK. An empty coffee cup is still a coffee cup. The coffee cup itself did not disappear after the last drop is gone.
There are cases where it might be desirable for a collection resource to 404. For example, if you want to indicate that a collection never existed or never has been created.
One way to think about this is the difference between an empty directory or a directory not existing. Both cases can 'tell' the developer something else.
You're trying to access a resource which does not exist. That's the reason for 404.
As a simple google search says
The HTTP 404, 404 Not Found, and 404 error message is a Hypertext
Transfer Protocol (HTTP) standard response code, in computer network
communications, to indicate that the client was able to communicate
with a given server, but the server could not find what was requested.
For your case
{
"value": []
}
This can be a status code 200 which means the resource is accessed and data is returned which is an empty array or you can customize it to a 404. But for that you've mentioned best is to return 200.
A status code of 404 is the correct response for when there is no resource to return based on a request you made. You asked for data and there is no data. It returns an empty response. They're relying on you to base your interpretation of the results on the status code.
https://en.wikipedia.org/wiki/HTTP_404
Some companies prefer making their errors known instead of hiding them. I know where I work we shy away from try catch blocks because we want our applications to blow up during testing so we can fix the problem. Not hide it. So it's possible that the dev that created the API wants you to use the status code of the response as a way of telling if the service was successful.
Related
In our API, one of the endpoint will expect clients to provide body/payload only in certain scenario.
If the API is unable to generate a payload for given request based on the origin of the client then, we want our API to provide response with the right status code to the client, so that they know they have to provide additional information. Once the client fulfills the request with body/payload then the api will process the request as normal.
I just wanted to know is there any standard, predefined status code or procedure to implement this kind of endpoint in API design or do we have to just reject the request with some custom status code and then ask the client to implement a logic based on custom code?.
Thanks,
Vinoth
HTTP Status codes don't, nor are they intended to, map precisely against every real world error. They represent categories of error.
For example, a 404 means that the resource couldn't be found, but if your path is /customers/11/animals/5 then there are several things which could be wrong with the path. customer 11 may not have an animal 5 for example, or there may be no customer 11. There is no http response for "animal not found". Or your API may not have any calls with that pattern of URL to begin with.
You should return a status code which represents what "category" of error you have (in this case, something was not found), and the response body should contain more specific details about the error. To make things simpler, I find it helpful if the data structure is the same for a success and error (it makes parsing much easier) with a "data" field which varies per response.
Here is one example:
status code: 404 not found
body: {
"messageDetailCode" :"CustomerNotFound",
"messageDetail" : "Customer not found",
"data" : null
}
Further reading:
What's an appropriate HTTP status code to return by a REST API service for a validation failure?
I'm building a REST API and have a dilemma around the returning response code to a GET operation.
I've found many examples and answers online but not for my particular scenario.
Here is what I have found and understand so far:
if returning an empty list (say /library/authors/{authorId}/books) an empty list with a response code 200 will suffice
if requesting a specific resource with an id ( say /library/authors/{authorId}/books/{bookId} ) the response will be empty with a 404
That summarizes most of my use cases and I am fine with it.
However, what happens if I access a sub-resource without an id?
For example, for arguments sake, let's say the author can have many books, but only one auto-biography. He either has one or he doesn't. I don't expect the user to pass in the auto-biography id because the system can figure out on its own if one exists, the endpoint is something like this:
GET /library/authors/{authorId}/auto-biography
If the author exists but he has no autobiography (it is NULL), would the http response code be:
204 (empty content)
404 (resource does not exist)
Thank you in advance!
Working through the semantics
GET /library/authors/1/auto-biography
/library/authors/1/auto-biography is an identifier. The resource itself is some concept like "the auto biography of author 1"; notice that we can talk about the resource even though it may not actually exist yet.
A resource can map to the empty set, which allows references to be made to a concept before any realization of that concept exists
The thing that appears in the body of the HTTP response isn't the resource, but a representation of the resource.
So now look at the status codes
404
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.
204
The 204 (No Content) status code indicates that the server has successfully fulfilled the request and that there is no additional content to send in the response payload body.
A loose analogy: suppose you try to get the contents of a file. 404 is semantically aligned with FileNotFound; 204 indicates the file is zero bytes long.
404 would normally be accompanied by "a representation containing an explanation of the error situation, and whether it is a temporary or permanent condition." It indicates that the client tried to use a link that shouldn't have been available.
204, on the other hand, doesn't have anything -- the representation is zero bytes long, how could there be data. It's a special case of a 200 response, advising the client (and intermediary components) that the response body is intentionally left blank.
I am wondering what status code would I response with in my else statement from the code below:
if (album) {
res.status(200).json({error: false, data: {channel_id: album.attributes.channel_id, id: album.id}});
} else {
res.status(200).json({error: false, data: {message: 'There is not album found with this name'}});
}
I don't want to leave both of them 200 as I want from front end to manage messaged thru status code, for ex if it returns 200 I would say "Created Successfully" while in else case I would display "No data found".
What is your suggestion?
"No data found" should be 404.
"Created Successfully" should be 201.
For the 201 you should also specify a Location header for where another request can access the new resource.
Refs:
201 http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.2.2
404 http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.5
UPDATE:
I thought I'd expand on this, because the comments below point to thought processes I've battled with myself.
GET /some/thing responding 404 Not Found may mean a database entity not found, but could also mean there is no such API end point. HTTP itself doesn't do much to help differentiate these cases. The URL represents a resource. It's not a thing in itself to be considered differently from the thing it represents.
Some APIs respond 400 when a request is made to a non-existant endpoint, but personally I don't like this as it seems to contradict the way web servers respond to normal resource requests. It could also confuse developers building client applications, as it suggests something is wrong in the HTTP transport rather than in their own code.
Suppose you decide to use 404 for missing database entities and 400 for what you consider bad requests. This may work for you, but as your application grows you'll uncover more and more scenarios that simple status codes just can't communicate on their own. And this is my point..
My suggestion is that all API responses carry meaningful data in the body. (JSON or XML, or whatever you're using). A request for an invalid url may look like:
HTTP/1.1 404 Not Found
{ "error": "no_endpoint", "errorText":"No such API end point" }
Although, I agree with above post, I would also consider HTTP status 200 for some cases.
For example, you have Post and Post_Comments entities. When you request comments for give Post Id, you can have either have 404 (an error which you then need to handle on your REST API consumer side) or 200 which means that everything is OK and an empty array is returned. In the HTTP status 200 case, you do not need to handle an error. As an example, see how FB treats HTTP codes https://apigee.com/about/blog/technology/restful-api-design-what-about-errors
To follow and unfollow a person via a RESTful API, I have
POST /person/bob/follow
DELETE /person/bob/follow
What should these return in the body?
A collection of everyone you follow
The person you just followed / unfollowed
A status like { status: "ok" }
Nothing.
If you respond on errors using a HTTP server status, the status code does not say anything. If you respond with a 404 Not Found if there is no user Bob, or a 500 Internal Server Error if the database is broken, the only successful response you will ever get is OK. Users do not have to check the status code, they only have to check the HTTP status code.
I suggest you return nothing, and the fact that it is a successful response (i.e. 200 OK or 204 No Content) indicates that the operation was successful.
It all depends on your app/API design and the contract you are gonna define with the client/callers. But generally, in all the cases you should return status code to make your client aware of the result.
Like: respond(ResponseCode::OK, ...)
For POST: I'd return 'bob' object containing all of his followers + status code
For DELETE: I'd only return the status code.
Generally, for an API, I'm apologist to use the HTTP status codes instead of always OK with a code defined status.
This means that you can follow the existing standards for answers, and anyone who gets an error code will know roughly what happened/what they have to do.
Take a look at the wiki article http status codes for a usable reference manual.
Also, together with the error code, and because is an API we are talking about, it is useful to have a more descriptive message about the error. Something meaningful like error: "Auth token missing", or whatever standard you might come up with.
When it comes to creating resources, I generally answer back with 201 (Created) and the resource just created. Keep in mind that you might want to exclude some attributes from the resource (e.g. You're creating a user, you shouldn't return sensitive info such as the encrypted password)
Regarding the deletion of resources, generally return with either 200 (Ok) or 202 (Accepted) and no extra info.
Nevertheless, As #yek mentioned, it highly depends on the commitment with the API consumer. The most important thing is that you document the API decently and explain what should be the expectations.
We're authoring REST services, and there's a debate on what to do when someone requests a resource with a parent ID that does not exist.
Example: You are asking for a list of people associated with a company, so you GET with ID 1, but that company ID does not exist.
I would argue that the definition of REST says that we would simple return a empty list (resulting in a HTTP 204 (No Content)), since a HTTP Bad Request is for only malformed syntax, per the specification:
http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
The request could not be understood by the server due to malformed syntax. The client SHOULD NOT repeat the request without modifications.
I think it's also clearer that there was no error to be interpreted, the resource you are requesting does not exist.
Thoughts on best practice?
There is a SO discussion here: HTTP 400 (bad request) for logical error, not malformed request syntax although it's a bit more abstract, I'm torn if I should post this, or simply use that question.
If you do
GET /company/1
and there does not exist a company with id 1 then I think the appropriate HTTP status code is 404 - not found.
However, if you were to do,
GET /companies?id=1
Then I would return a 200 and an empty list of companies.
204 is not an error code, it is a success code, but that's a quibble. I don't often see it for empty lists, but rather success responses that simply have no meaningful content to respond with, such as a successful DELETE. For example, if you are returning JSON, a 200 with content of [] is what I would expect of an empty list of results. However, I don't think it is incorrect to use it in your case.
404 Not Found is a more common error for the case you describe. You are correct that it is not a syntax error, so 400 is not appropriate, but in fact, the resource is not there. 404 Not Found is an accurate response.
But in choosing between 200, 204 and 404, the correct answer is: it depends. The question is whether it is an error or not. 404 is more expressive (the client can tell that there is no such company) but you can trade expressiveness for security, meaning that it might be a good thing that a client can't tell whether the company with that id exists or not.
What about caching? only 200 will get cached, both 204 and 404 won't get cached. If this is important 200 with empty list seems ok. Not sure what about empty single elements?