Hi, guys! This is my first post on Dev.to.
I come to share with you a thought that intrigues me a little. Maybe, a little strange one at first sig...
For further actions, you may consider blocking this person and/or reporting abuse
I think the "principle of least astonishment" would dictate
404
to me personally, but this is definitely a juicy topic!IMO 404 all the way 100% o long as we're talking about REST.
The whole REST architectural style is predicated on the idea that the state of a resource at any given moment is temporary:
Source: Fielding dissertation 5.2.1.1
The idea of the current resource state is hinted at in the immediately following line of the referenced RFC 7231 section 6.5.4
In other words: the resource does not exist in this API at this moment. However, it might one day. Who knows. But it is 404 Not Found right now.
Reading just one sentence further in the definition of 404 in RFC 7231, you find out that there's a response code for if the resource was there at one point, and is now permanently no longer there:
This indicates the shared understanding of the author of the RFC of a resource as the mapping to an entity. The entity changes, it has state, but the mapping does not. The mapping identifies that entity permanently.
So to address the issue raised in the above article:
The main reason I believe this is not an accurate interpretation is that the mapping does not exist. And since the resource is the mapping, 404 is the only logical decision.
Besides that, there's already an implicit understanding that if you receive a response, "the structure of the URI" is fine.
Finally, at the end of the day, I think it logically doesn't make sense to tell API consumers 204 No Content or 200 with a null payload, because you would make them think you do have a resource for that given ID within your API, but you're just storing all null values.
This semantic confusion would create similar issues to hash table data structures in some languages that return null values for keys that aren't in the table. Does the null response mean that the key is in the table and currently has the value null? Or does it mean the key isn't in the table? Same problem, and best to avoid.
AHHHH I’ve flipped my opinion on this so many times just on this page!! I have no idea, I think either is ok as long as an API is consistent it’d be annoying if one endpoint returned a 404 if the record didn’t exist and another endpoint in the same API returned a 200 with null data.
I think as long as they’re consistent either is totally fine. I think. Or do I?! I just don’t know anymore 🤯
Why add the burden of checking whether the response comes back with a null or not to the developer that uses your API?
501 Not Implemented or 405 Not Allowed, for endpoints that do not exist (boocs, in your case)404 Not Found for resources that do not exist (or the user has no access to)
200 OK for succesful queries that return data
If the database is part of your application, go ahead with 404. If not, why to lean your app on it? It's just another perspective of how to look at the application. The RFC keeps ruling.
If a resource is requested with an invalid ID, then either:
I would be very wary of responding with a 2xx code, as the caller may well assume they have what was asked for and misbehave.
That said, I recommend RFC7807 error messages should always accompany an error response, to add machine-readable nuance that status codes do not permit: tools.ietf.org/html/rfc7807 :)
Returns a 404, because the URI points to something which does not exist
Returns a 200, with a null response because it's a query for a record which does not exist.
Returns 400 with this body
Going to disagree with this as it's a leaky abstraction, exposing the unnecessary detail of having a database to the calling client.
Whether or not a database is queried to check if the book in fact exists or whether all books are simply static pages (though that's often not feasible) should not actually matter to the client. Unless the API is able to reply the other path of
GET /boocs/8c2ba535-5523-47a5-8a72-281c316d5fc4
with a similar response such asthen I don't think there's actually full consistency and a clear abstraction being made
404 all the way. It's client error because it didn't supply correct ID.
If a message is needed, RFC suggests using object type called problem details. It is standard type to transfer error messages and it can be extended to contain additional information 🙂
My rule of thumb is that an endpoint should only have a single successful response type and code.
The docs say: developer.mozilla.org/en-US/docs/W...
So Sorin's comment 204 - no content kind of makes sense.
Then i think, well what if that book exists, but is just currently not available?
Getting a blank "no content" doesn't tell you what's actually wrong with your request or with the data.
Ben's note about a 404 is also what's often taught these days as far as error responses go and you can put a message in the response header itself [which almost everyone i know doesn't even know is possible so they completely overlook it]
Personally, I hate it when an endpoint returns a generic response header with no message on error.
*Because you don't know if the endpoint is failing, or you passed in the wrong path, or the data requested doesn't exist. *
I much prefer a 200 response: The request has succeeded
[so you know the endpoint works and received your info correctly]
It should respond with a response object with status: failed and msg: "No go buddy: because x y z" that tells you exactly what's wrong with your request info, since the server was successful in processing it and respond.
This way you know what to do to fix it.
What you're looking for is called "204 - No Content"
Hi Sorin Costean!
I don't think so. If you have an endpoint to get a list of books and make a request to it. What would it be that response? A empty array with
200
status code or204
with no content? I think the first response fits more the client expectations than the second one. Why would it be different for a single resource?Marco, what i usually do is
If the request came on a list endpoint and there's no content i return
200
with a empty list, if the request is for a single record and the record doesn't exist i return204
.Normally my "pagination" responses retrieve another useful data as well like "next_page", "count" and etc, so it makes easy for validation if the response is "200".
An empty list is no content as well. Why not use 204 for it?
If you have no items for the list, returning an empty list will yield the full available content. Maybe you will also add some metadata (e.g. total number of entries) to support pagination. Your consumer will not have to treat this differently from a filled list. When requesting a single item that does not exist, users would have to examine the content and see if they can work with it. And from my experience: if you start seeing surprising responses, the trust in the responses from this system drops rapidly.
This is something that depends on the interpretation of the RFC as well as the intended "protocol". If you want to be RESTish, the book with the given id is a resource and if that resource does not exist, The best response in my opinion is the 404. Giving a 200 with a null or empty response is more or less an encoding trick. The consumer will have to check the content for certain criteria first. I'll admit that checking the status code is nearly the same check, but why would I want to throw away this means of expressing something about the result and replace it with something that is not defined in the RFC? I'm my opinion, that's the way of communicating clearly.
When you imply that you don't see the database as a part of your application and rather a data repository: I totally agree, but I draw different conclusions from this. Even though the database will know whether a book exists, it does not really define whether it exists. This definition is done by the users of your system when they create books. They will not care where it is stored though, as long as no data will be lost. And if we assume that the database is consistent, a user asking for a book (represented by an UUID) that does not exist is asking for something that really does not exist. It's not just a syntactical error in the user's side. So I still think a 404 is the way to go here.
Having said that, I also have my problems with the RESTish approach of CRUD operations, as we will often want to restrict which changes a user can do at a given time in real-world applications. I do prefer going with a more CQRS-like way of having commands to perform certain operations in a resource. But that would open another large discussion.
Returning empty for "data not found" forces the client to check both return status and the content returned. This approach does to save the client from checking the return status because they need to check for errors resulting from environmental faults anyways.
"If you have nothing to give, give nothing [...]" is correct in the form of a "not found status", not in the form of a made up content albeit empty. Besides, can the client use an empty payload in all cases when it is expecting a predefined model in the content? It is just pretzel programming to torpedo established client expectation.
Was getting bit by this recently and Im also a bit confused on the right approach. There is the spec that everyone keeps talking about. But from a FE perspective, there is so many times I do these kinda GET apis, where I show or hide UI based on the response.
When the server sends 404, it goes into my generic error handling code. Now I need to write conditions there to tell it to ignore this 404 cause my UI knows how to render this response.
I would have preferred the server return 2xx for these situations so that my generic error handling is there to handle actual errors.
Also it creates a lot of noise in the devtools and error tracking tools when you expect certain api's to not have a response.
Maybe something like Axios interceptors will help for my first problem.
I prefer 404 too