Software Engineering
api-design error-handling http-response
Updated Tue, 26 Jul 2022 23:03:01 GMT

Should a REST API return a 500 Internal Server Error to indicate that a query references an object that does not exist?


I am working with a REST API which resides on a server that handles data for a multitude of IoT devices.

My task is to query the server using the API to collect specific performance information about said devices.

In one instance, I obtain a list of available devices and their corresponding identifiers, then later query the server for more details using those identifiers (GUIDs).

The server is returning a 500 Internal Server Error for a query on one of those IDs. In my application, an exception is thrown and I don't see details about the error. If I examine the response more closely with Postman, I can see that the server returned JSON in the body which contains:

errorMessage: "This ID does not exist".

Disregard the fact the server provided the ID to begin with -- that's a separate problem for the developer.

Should a REST API return a 500 Internal Server Error to report that a query references an object that doesn't exist? To my thinking, the HTTP response codes should refer strictly to the status of the REST call, rather than to the internal mechanics of the API. I would expect a 200 OK with the response containing the error and description, which would be proprietary to the API in question.


It occurs to me that there is a potential difference in expectation depending on how the REST call is structured.

Consider these examples:

  1. http://example.com/restapi/deviceinfo?id=123
  2. http://example.com/restapi/device/123/info

In the first case, the device ID is passed as a GET variable. A 404 or 500 would indicate that the path (/restapi/deviceinfo) is either not found or resulted in a server error.

In the second case, the device ID is part of the URL. I would be more understanding of a 404 Not Found, but still could argue based on which parts of the path are interpreted as variables versus endpoints.




Solution

I think a 404 response is the best semantic match here, because the resource you were trying to find (as represented by the URI used for the query) was not found. Returning an error payload in the body is reasonable, but not required.

According to RFC 2616, the definition of the 404 status code is:

10.4.5 404 Not Found
The server has not found anything matching the Request-URI. No indication is given of whether the condition is temporary or permanent. The 410 (Gone) status code SHOULD be used if the server knows, through some internally configurable mechanism, that an old resource is permanently unavailable and has no forwarding address. This status code is commonly used when the server does not wish to reveal exactly why the request has been refused, or when no other response is applicable.





Comments (5)

  • +6 – 404 is only a semantic match if the id that doesn't exist corresponds to the resource that is being retrieved. — Mar 23, 2018 at 16:43  
  • +0 – @ThomasOwens A query returning no results would return 200 status and an empty array of results. A 404 would only be returned when specifying a specific object ID that does not actually exist. — Mar 23, 2018 at 17:19  
  • +0 – @ThomasOwens: from the caller's pespective, the endpoint isn't /questions, it's /questions/368213. That endpoint doesn't exist in your scenario. Think of it this way: if you do a GET on /foo/bar and there is no bar, why should the response be different if /foo exists or not? — Mar 23, 2018 at 19:59  
  • +0 – Right, it's not a server error so we don't send a 5xx. It's a client error - the client asked for something don't have, so we send 4xx, specifically 404. — Mar 23, 2018 at 20:28  
  • +7 – @ThomasOwens: How do you differentiate between a 404 meaning "the query returned no results" and a 404 meaning "the endpoint does not exist"? -- 400 Bad Request. — Mar 23, 2018 at 20:31