11 ms·
Many API developers misuse/overload HTTP status codes when they should actually be using application specific status codes delivered via a wrapper to the respon
by grandalf 9y ago
Many API developers misuse/overload HTTP status codes when they should actually be using application specific status codes delivered via a wrapper to the response.
Any time an API returns a correct response the HTTP response code should be 2xx. Many developers use 4xx status codes to indicate things like data validation errors or other things that are not part of the HTTP transport.
HTTP is the transport layer, and any application specific scenarios are best handled with a custom error namespace that can be returned within any 2xx HTTP response.
Generally speaking, if the HTTP layer is returning 5xx you have a server problem and client code should not know anything about that or do anything but retry. If the HTTP layer is returning 4xx then the client is likely poorly designed or misconfigured.
But for typical client operation, when there is no server error or client design/configuration error, HTTP responses should be 2xx or 3xx and any additional detail should be handled in an application-specific way, not by overloading the meaning of HTTP response codes, which are for transport-related concerns only.
- jsiepkes 9y agoWhile I'm inclined to agree with you the makers of SOAP don't seem to share your opinion. Any SOAP fault must be send with an HTTP 500 according to the spec.
- grandalf 9y agoMy take on SOAP's approach is that it isn't overloading HTTP status messages, it's attempting to impose SOAP's message structure on things that are legitimately HTTP 5xx responses, so that the soap client can handle some of those failure modes and the programmer doesn't have to engineer another protocol for dealing with transport errors or parse a different message format. Notably, SOAP is not just doing REST it is attempting to offer an abstraction for dealing with transport issues. Most people designing a REST or rpc style API do not attempt this breadth in their API design, instead they just overload HTTP response codes (from the HTTP and webDAV specs) to handle application-specific stuff, which ends up resulting in the codes being effectively meaningless across applications. SOAP, on the other hand, is meant to be used in the same way across applications. So if your app uses SOAP to consume multiple SOAP APIs, and you engineer failure handling for the HTTP 500 associated with some kind of SOAP fault, chances are you can reuse this logic with all of the SOAP APIs. On the contrary, many REST APIs that overload HTTP statuses do it in some arbitrary way defined by the team working on the API, so the consumer can't make generalizations about the meaning of the error codes in the common cases where one might determine (for example) a retry to be necessary.
- leejo 9y ago> Most people designing a REST or rpc style API do not attempt this breadth in their API design, instead they just overload HTTP response codes (from the HTTP and webDAV specs) to handle application-specific stuff, which ends up resulting in the codes being effectively meaningless across applications. HTTP status codes exist to be overloaded, especially in the 4xx range. As per the IETF: https://tools.ietf.org/html/rfc7231#section-6.5 https://tools.ietf.org/html/rfc7231#section-6.5
- grandalf 9y ago> HTTP status codes exist to be overloaded If you look at most of the status codes they pertain to the transport itself: content negotiation, content size, etc. In other words, the client would be pleased to see one of those codes when making a request and wondering "Why is this not returning the data I expect?". Compare this to a typical scenario in an application of signing up a user. If the user types in a password that does not meet the password complexity requirements or chooses a username that is already taken, there was not a problem with the transport mechanism, there is an application-specific constraint that the programmer calling the API did expect to encounter some of the time, because of course both of these are common scenarios. If for some reason the application code does not limit usernames to a small number of characters and the API returns an HTTP 413 status, that is unexpected to the programmer, so the non-200 code is appropriate. The programmer needs to rethink the transport assumptions assuming that super long usernames are OK. The distinction is that HTTP errors apply to HTTP itself. Are the basic requests and responses functioning properly, etc. But application-specific things generally belong in a separate layer of metadata. I've seen some very very bad API designs that totally misuse HTTP status codes, largely influenced by the old jQuery pattern of a success and failure callback, with 2xx triggering the success callback and 4xx and 5xx triggering the failure callback. How many times has some server error resulted in confusion because the error callback is being used to handle routine flow control in the application code.
- leejo 9y agoI'm relatively agnostic about this, but having developed integrations for many APIs I generally prefer those that use HTTP status codes + error payload for client side errors, rather than 200 OK + possible error payload, as they're much easier to deal with on the client side. There are no unexpected status codes if your API is fully documented. I gave a short talk about this last year: https://www.youtube.com/watch?v=9w4dNi2wu_E&feature=youtu.be&t=16981 https://www.youtube.com/watch?v=9w4dNi2wu_E&feature=youtu.be...
- libeclipse 9y agoThe S stands for Simple http://harmful.cat-v.org/software/xml/soap/simple http://harmful.cat-v.org/software/xml/soap/simple
- akvadrako 9y agoWhy do you think that? An application-level failure is a "server problem". It's possible there is nothing between the OS handling TCP and your application. This is also against the concept of REST and traditional HTTP servers, which do use HTTP error codes.
- grandalf 9y ago> It's possible there is nothing between the OS handling TCP and your application. This does happen, and it results in the client having to have ad-hoc code to deal with a nearly infinite number of possible "Server error" scenarios, some of which may be normal functions of the API and others which may actually be server failures. > It's possible there is nothing between the OS handling TCP and your application. I'm not arguing that one shouldn't use HTTP status codes, I'm arguing that they should be used only for the standard meaning of the code, one should not need to consult a table provided by the API designer to determine which 4xx HTTP status codes warrant a retry, and which 5xx status codes are normal vs exceptional situations. Suppose you make a call to an API and it returns 5xx because you provided a parameter value that is valid in the URL or payload but invalid in the app (suppose your app doesn't allow usernames that are profane words, for example). The response should not be 5xx, it should be 2xx with a message indicating the application's preferred range of values. 5xx means that something went wrong on the server trying to fulfill the request, 2xx means that the request was fulfilled properly, and any additional info relevant to the client should be passed along as part of that 200 response. > This is also against the concept of REST Very few APIs can be designed well as 100% REST. Lots of very typical scenarios necessitate jumping through a lot of hoops to use REST in a pure way. REST fights with database normalization in some cases and with many authentication scenarios. It can also require the client to maintain a fairly elaborate (and brittle) representation of server-side state that is mostly unnecessary. REST makes sense when there is a perfect alignment between REST verbs and data flows, but when you get into a situation where it's necessary to make multiple API calls to do one logical operation, it would probably have been simpler not to use REST in the first place and to have just designed a simple, clean, non-REST API.
- akvadrako 9y ago
- gldalmaso 9y agoI disagree. HTTP is a widely known standard with a ready to use client/server implementation in basically any platform. Leveraging that semantically in API seems to improve productivity all around. Are there any major trade offs? The alternative is making standards for how to format the payload and try to get everyone on board while also trying to manage another half a dozen or more legacy implementations of non-standards. Or don't make standards and live with the fact that every API will do its own thing and you have to handle everything differently each time you have to talk to anyone. As a practical example, I would really prefer not to have to parse a XML response to get a status code in my js frontend, nor would I'd like to examine it via string/regex matching.
- grandalf 9y ago> Are there any major trade offs? Yes, see my other comments in this thread.
- marrs 9y agoMany developers use 4xx status codes to indicate things like data validation errors or other things that are not part of the HTTP transport. You mean like a form validation error? Surely an invalid request is a bad request. No?
- grandalf 9y ago> 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?
- Muanh 9y agoYou could use 422.
- grandalf 9y ago422 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.
- vfaronov 9y ago> 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).
- grandalf 9y ago> 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.
- caseysoftware 9y agoNo. You should never, ever, ever return a 2xx status code with an error payload. The 2xx series means "Success" and you're abusing HTTP to use it to mean anything else. With regard to application layer vs transport layer, the 404 Not Found, 406 Not Acceptable, 409 Conflict, and many others errors are specifically application layer codes. If you can't get a more specific code, 400 Bad Request with an expressive payload is useful. The 500 codes are generally transport layer. The reason that APIs are getting easier and easier to understand and use is because we're using the same design patterns consistently and repeatedly. Therefore, the understanding you gain from the Twilio API can be applied to Stripe. If you use existing tools in new and "innovative" ways that are contrary to - instead of in addition to - to their intention, you're setting back adoption and making your users re-figure out basic things. Don't. Or worse, people don't realize how you're misusing the tools and build flawed systems. (The one exception I'd give you is 202 Accepted which is generally used for "we've accepted this for now but processing and final validation may occur later" - it's a tentative success message.)
- eric_b 9y agoUh what? If the request was appropriately formatted, not too large, and generally acceptable to the server from a transport perspective, why shouldn't it succeed with a 200? Error handling is an application level concern, not a transport level concern. HTTP status codes lack the nuance required to inform the end user about errors in any non-trivial application. I personally enjoy the OP's solution. I've worked on dozens of REST APIs in my life, and I always prefer those that contain a response envelope complete with metadata and error responses. Pre-emptive edit: When I say error handling is an application level concern, I don't mean "application" from an OSI model perspective, which is narrower in scope than what I'm talking about.
- caseysoftware 9y agoExpressive error messages are great. Calling errors a "success" is wrong. Check out my slides here for more: https://speakerdeck.com/caseysoftware/12-reasons-your-api-sucks-2017-rev https://speakerdeck.com/caseysoftware/12-reasons-your-api-su... Slides 38-40 are specifically about expressive and useful error messages.
- dragonwriter 9y ago> HTTP is the transport layer No, HTTP is the application layer. TCP is the transport layer. > and any application specific scenarios are best handled with a custom error namespace that can be returned within any 2xx HTTP response. No, generally application errors should be 4xx or 5xx codes; greater detail can be provided in the payload, sure, but a proper error condition should be returned, 4xx for errors resulting from the client request being unacceptable in some way, 5xx for other errors (which are, necessarily, server errors.) (If you are tunneling another application-layer protocol over HTTP, your argument makes sense, but that's not the general case with APIs.)
- grandalf 9y ago> (If you are tunneling another application-layer protocol over HTTP, your argument makes sense, but that's not the general case with APIs.) I'd argue that that is actually what most APIs are doing that are not purely "REST" operating naively on resources. As we move up the protocol stack, one is the transport for the next. HTTP is not really the application layer protocol, it's a transport for a protocol defined by the API, at least for any API nontrivial enough to benefit from its own specific error/response codes.
- deleted 9y ago[deleted]