5 ms·
In my opinion, a rejection is an expected outcome, and therefore should have a response code of 200. You're not asking, "Does this card exist?", and sending a
by citrusx 7y ago
In my opinion, a rejection is an expected outcome, and therefore should have a response code of 200. You're not asking, "Does this card exist?", and sending a 404 if you have no record. You're asking a remote system to do a job for you, and if that job completes successfully, it's a "Success" in the HTTP world.
At that point, you rely on the body content to tell you what the service correctly determined for you. A result that the user doesn't like is way different than a result that comes about because something was done wrong at the client side (4xx) or a failure on the server side (5xx).
- meowface 7y agoI think this is the exact right way of looking at it. 4xx/5xx are for layers that are below the business logic (like "is the web server able to route this path", not "did the application successfully validate the user's input data and allow them to continue on to the next step in a process"). It can get a little fuzzy for 401 and 403 errors, though; those seem to be returned by APIs pretty often. Not entirely sure how I feel about that, but I think those are a bit more sensible.
- jacobgreenleaf 7y agoThe HTTP IETF RFC (2616) states: > The first digit of the Status-Code defines the class of response. The last two digits do not have any categorization role. There are 5 values for the first digit: > - 4xx: Client Error - The request contains bad syntax or cannot be fulfilled What do you think status codes like 404, 405, 406 are for? You say they shouldn't be for "did the application successfully validate the user's input data" but status code 400 is explicitly for bad requests. In your view should a HTTP server ever return 4xx?
- meowface 7y agoIt depends how you define validate. If the HTTP headers are malformed, sure. If a JSON or XML API receives malformed JSON or XML, sure. But if it's "register this account" and the username already exists, or "pay with this credit card" but it's not a valid credit card number, or "process this invoice" but the total is missing, then I think it should be a 200 status with an error message. It's validating the request was received and loaded by the application vs. validating the business logic requirements for the request's data payload. Obviously if you send a TAIL method request, you should get a 405, and if you send Accept: eggs/*, you should get a 406. If a route doesn't exist, you should get a 404. If you fail HTTP basic auth, you should get a 403 (but why are you using HTTP basic auth?). If you want certain paths to never be accessed for some reason, you should return a 401.
- sagichmal 7y ago> You're asking a remote system to do a job for you, and if that job completes successfully, it's a "Success" in the HTTP world. But a provided credit card number not existing is not success, it is unambiguously a failure. HTTP is a transport but its response codes are clearly designed to map somehow to the "business logic" of the thing underneath it. We have to twist ourselves up in knots to map most of our business systems to the set of status codes that make sense for the default HTTP-fronted application (Fields' thesis stuff) but that's what we sign up for when we decide to expose our business services via HTTP. Other transports require different contortions.
- hugelgupf 7y agoIt is a failure, but not of the HTTP service. It's a failure of the RPC call. 404 means "this API doesn't exist", not "the API exists but it returns an error"
- sagichmal 7y ago404 does not mean "this API doesn't exist". It means, quote, 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. Resource here is a transport-level (HTTP) representation of a business-logic concept, in most cases a document, but if your HTTP server happens to front a credit card validation service, potentially a credit card. Or a user. Or a recipe.
- stingraycharles 7y agoExactly. The parent is thinking along the lines of “but when the error is thrown successfully, it actually means success!” and at the same time missing out on an opportunity to leverage a well-understood error handling standard in HTTP.
- nulagrithom 7y agoAgreed. What else would you use 400 for? I don't see how sending back 400 is going to hurt. The payoff of using 400 is you can watch your 400 rates with almost no effort (HTTP is well established and there's many many tools out there.) If you somehow start accidentally munging the card number sometimes or if your card processor starts doing wacky stuff you'll see a spike in 400 rates. If it was really that troubling that declined cards are expected, I would personally at least want to see 200 come from the internal API and 400 go out to the client. And if your "intermediate devices" start doing goofy stuff to 400's then you've got bigger problems... 4xx's shouldn't be taking nodes out of prod. That's wack.
- stcredzero 7y agoYou're not asking, "Does this card exist?", and sending a 404 if you have no record. Doesn't this depend on the nature of the REST API? (Though putting a credit card number on the path doesn't seem like a good practice.)
- bandushrew 7y agoIts the difference between whether you believe you are using HTTP as a transport mechanism or you believe you are using it to create a DSL protocol. Personally I prefer to think of HTTP as a transport mechanism, with business logic at a higher level. The question "If I replaced this http transport with, say, FTP or a dvd drop, would it require changes at the business logic level?" feels important to me. That preference puts me on the wrong side of history at the moment though, and Im going with history. Lets express our business logic through the error system provided by our transport mechanism instead....