3

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.

Community
  • 1
  • 1
  • I tried out Jersey (JAX-RS) default for an empty list. If you return a null list, you get the empty list in JSON and a 204 error as well. Not to say that's the right behavior, but it's a datapoint. – Geoffrey Clapp Sep 05 '11 at 00:02

3 Answers3

6

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.

Darrel Miller
  • 139,164
  • 32
  • 194
  • 243
  • I tried out Jersey (JAX-RS) default for an empty list. If you return a null list, you get the empty list in JSON, but you get the 204 error as well. Doesn't make it right, just an example. Agree on the 404, in a strict REST interpretation, I would think it would do that as well. – Geoffrey Clapp Sep 04 '11 at 23:59
  • Using Jersey, if you request GET /companies?id=xyz where id is supposed to be an integer, it will give a 404 instead of a 400. I'm not sure if that's Jersey or JAX-RS. In the case where it is an id, a 404 makes sense, but in the common case of having query parameters for some sort of search criteria, you would either want a 400 or to simply return no results as there is no such id. Just reinforcing that, while a good first default might come from a spec, the best answer depends on the context. – jhericks Sep 05 '11 at 02:28
  • @jhericks great example of the point you wanted to make - thank you. Appreciated. – Geoffrey Clapp Sep 06 '11 at 04:10
3

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.

jhericks
  • 5,833
  • 6
  • 40
  • 60
  • Fair point on the quibble, I should have called it a status code. Given I quoted the spec and that's the same they use (for the general case of codes), I removed the word error after 204. Technically, you are right to call it out and technically is the name of the game here, so I changed it in the title and removed it from the 204 reference – Geoffrey Clapp Sep 05 '11 at 00:04
0

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?