1

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?
2

2 Answers 2

5

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

2
  • I hear what you're saying, but what it makes me think is that there isn't a well-defined status code for a POST request sending illegal data in the value of key-value pair of form data. And hence, the status code to be sent becomes open-ended - and so this question arises. But 400 probably makes most sense. Is that so? The RFC for 400 doesn't explicitly state this use-case - but I think this is something that really should have been thought through! Jul 10, 2019 at 9:25
  • Nop. The RFC will never explicitly state any use-case. At most, it will make some comparison or give an example (without any context). The RFC refers to generic cases without going deep into details or causes. That is what makes the HTTP semantics reliable. It's impossible to cover all the use-cases and semantics implicit between a given client and a given server. HTTP is a protocol and it should just focus on the act of communication, everything else is irrelevant.
    – Laiv
    Jul 10, 2019 at 9:52
2

An important concept in REST is the uniform interface

REST connectors provide a generic interface for accessing and manipulating the value set of a resource, regardless of how the membership function is defined or the type of software that is handling the request. The naming authority that assigned the resource identifier, making it possible to reference the resource, is responsible for maintaining the semantic validity of the mapping over time (i.e., ensuring that the membership function does not change). -- Fielding, 2000

In the case of HTTP, what we have is an application whose domain is the transfer of documents (representations) over a network (Jim Webber, 2011).

So a REST API is a facade that makes our application behave like a HTTP aware document store.

Therefore, the appropriate heuristic for choosing status codes is to consider the codes that would be issued by a document store under similar circumstances.

This heuristic tells me that you are correct to recognize that 404 Not Found has the wrong semantics. It is specifically calling attention to the target uri contained within the request, and does not accurately describe an error in the message-body of the request.

400 Bad Request isn't wrong, but it probably isn't best. The current standard is deliberately ambiguous about what the exact problem might be, but the obsolete versions of the standard were clear that the status code indicated a malformed message (ie we weren't able to parse the http request).

You can dig through the IANA registry looking to see if anyone has specified a status code with useful semantics. One candidate that merits consideration for your case is 422 Unprocessable Entity.

The 422 (Unprocessable Entity) status code means the server understands the content type of the request entity (hence a 415(Unsupported Media Type) status code is inappropriate), and the syntax of the request entity is correct (thus a 400 (Bad Request) status code is inappropriate) but was unable to process the contained instructions. For example, this error condition may occur if an XML request body contains well-formed (i.e., syntactically correct), but semantically erroneous, XML instructions.

Note that HTTP compliant clients that don't recognize 422 MUST fall back to 400 processing.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.