HTTP 200 or 404 for empty list?

2020-06-12 06:08发布

问题:

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?

回答1:

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).



回答2:

  1. 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.



回答3:

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.