Hacker News new | past | comments | ask | show | jobs | submit login

> Surely an invalid request is a bad request.

Invalid to whom? Should a form submitted with a username that already exists in the system get a 500 response code? What's the server error?




I'd go with 409 Conflict, but I'd also accept 400 Bad Request

Incidentally, the RFC for 409 makes it quite clear that this touches the application layer:

> Conflicts are most likely to occur in response to a PUT request. For example, if versioning were being used and the representation being PUT included changes to a resource that conflict with those made by an earlier (third-party) request, the origin server might use a 409 response to indicate that it can't complete the request. In this case, the response representation would likely contain information useful for merging the differences based on the revision history.

https://tools.ietf.org/html/rfc7231#section-6.5.8

In any case, getting pedantic about what's "an error" and using 200 OK for everything that didn't fail at the transport layer is a super frustrating experience regardless of whether or not it's semantically correct. Please don't do that to consumers of your API.


Versioning a resource, per WebDAV is a very specific application.

> using 200 OK for everything that didn't fail at the transport layer is a super frustrating experience regardless of whether or not it's semantically correct

The semantics of my application's protocol do not necessarily mirror the semantics of HTTP, nor are the descriptive statuses semantically similar, since most HTTP statuses are simply about transport (even though a few touch on the "application" of URIs as resources).


Transport layer to me means TCP/IP. HTTP sits above that, in the application domain. If a user sends an invalid request then the response should be in the 400 band. If the server failed in some way to deal with the request (e.g. the database is unavailable), then the response should be in the 500 band.

I would typically decide what my response code should be depending on what I think the response should be.

If a user tries to register a new account then a successful outcome would probably be a new user resource. If the user tries to register a username that already exists, I'd also probably go with 409 Conflict as the user is trying to create a resource that already exists.


There's no mention of WebDAV in that RFC.

Would it kill you to send back a 400 status code upon an error? Having to check for { isError: true } or something similar is obnoxious. I don't see the value gain of responding 200 OK when the operation was not successful.


> when the operation was not successful.

Well, do you care about all the successful and unsuccessful aspects of TCP that underlie the connection? No, you just care that it was successful, allowing the HTTP request. Assuming that is successful, then your API "operation" can occur and return its result.


Some APIs I've seen just use 400 for all generic client-side errors, including request syntax errors, impossible requests, duplicate requests, etc.

I would argue that most of the time, for any sufficiently large application, you'll need to use application specific status codes anyway (as you said), so why bother trying to be specific with the HTTP error codes? Certain client-side applications parse out if the response is a 2xx, 3xx, 4xx, or 5xx, and log it differently. At which point you just need one of them to trigger the different logging behavior.

The only special case I can think of is 401, which you need to send to trigger the basic authentication pop-up window for most browsers.


Exactly.


You could use 422.


422 is from the WebDAV spec, which is not HTTP.

A big portion of the improper overloading of HTTP status codes comes from WebDAV status codes seeming appealing when in fact WebDAV is a very specific set of functionality that is not really analogous to the way most REST APIs work... notably WebDAV offers locking semantics.


> WebDAV spec, which is not HTTP

HTTP is not a closed protocol. There will never be a single document defining all HTTP methods, status codes and such. Nothing in the definition of status code 422 makes it inapplicable to non-WebDAV applications. It is as much standard HTTP as status code 400 is (both are “proposed standards” in IETF terms).


> HTTP is not a closed protocol.

I'm not arguing it is, it's an extension that adds specific semantics to accomplish a specific purpose.

But some developers look at WebDAV and see a lot of similarity with some of the application specific error conditions they are working with and decide that overloading HTTP status codes is a good idea, when it rarely is.


Here’s the standard for 422: https://tools.ietf.org/html/rfc4918#section-11.2. It’s not a WebDAV-specific error condition. People are right to see the similarity and reuse the status code. This is not “overloading”.


There will be cases where an HTTP status code matches perfectly with an application specific scenario, and in those cases using an HTTP status code is not confusing.

The confusion comes when the API developer tries to shoehorn all application specific errors into pre-existing HTTP status codes.

In most cases it is clearer to simply adopt a payload format that includes application specific error codes, so that the clarity of your API does not depend on its incidental similarity to pre-existing HTTP codes.

422 is a class of errors, not a catch-all for all similar scenarios one might encounter in building an API.


> In most cases it is clearer to simply adopt a payload format that includes application specific error codes

Absolutely. This is a common practice and there’s even a proposed standard for it (RFC 7807). But such a payload need not be sent with 200 (OK). It can refine the status code instead of overriding it.


> It can refine the status code instead of overriding it.

True, this is sometimes possible when (coincidentally) one of the HTTP specs or extensions defines one of the codes in a way that feels similar enough.

The mistake is to assume that there is already a code for everything and that one does not need to define application specific error codes, which is what many API developers do.




Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | Legal | Apply to YC | Contact

Search: