Rest API POST with illegal data in parameters: Bad Request or 404

apidesignrestweb

Take a hypothetical camera company providing an API to manage its users and cameras. Each user owns cameras, and every user of a camera has a role assigned (one of admin, operator, viewer – these are defined in a database, and we might add new roles later).

If I have a GET request that fetches details of a camera using a parameter in the URL itself, for example:

www.cameracompany.com/camera/{id} should return 404 when you enter an ID that doesn't exist – because you're hitting a URL that doesn't exist.

Question 1:

However, say we were hypothetically doing the same with a POST request (lord forbid we ever do) to www.cameracompany.com/camera and send {id} as a form parameter. Should it return 404 or 400?

I argue 400 because the URL exists, but the parameter data entered is wrong but I had a pretty heated argument where my colleague is convinced it should be 404.

Question 2:

To take a more concrete example, let's say we're trying to update the role of a user from admin to operator. The API endpoint is a PUT request to www.cameracompany.com/camera/user/ where you enter camera_id, user_id, and role. Say you enter valid camera and user IDs, but jargon for the role, what status code should the API return?

My understanding is:

  • 404 when a URL doesn't exist.
  • 400 when insufficient parameters are sent in a PUT/POST request. But should 400 also be sent when the number & names of parameters are right, but the data contained in them is illegal?

Best Answer

You could use 404 in both cases but semantically speaking it would be a little bit misleading because www.cameracompany.com/camera does exist. Usually, 404 means "resource not found, don't try again", but it could also mean "the resource might exist but I don't want you to know, stop trying"1.

One meaning or another, the most likely test any developer would do is checking whether the URL exists.

Since the resource camera exists, handles and processes requests, the problem is not at finding the resource, it's at processing the request. The server can handle the request but can't process it. It's somewhat a business or validation error that could perfectly be communicated through the 400.

Unlike 404, 400 means "ok, the resource does exist, the request has been handled but could not be processed because something is missing, wrong-formated or the content doesn't make sense. Fix the issues and try again".

Remember that HTTP status codes are always addressed to HTTP clients, not to the business, not the application. These codes should be handled and translated.

The key thing is that we send one or another when we want the HTTP client on the other side to behave in a very specific way. This is not obvious with 4xx status codes but thinks in 3xx status codes that can make HTTP clients follow redirections.

In line with the note above, 404 is cacheable (by default). So, even if we change the wrong id with a good one, the HTTP client (or any other element within the network topology) might have cached the previous response and keep responding 404 Not found.


1: From the RFC - 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