I was always under the impression that 409 would be the "correct" code here, while you'd use 400 if the API user didn't supply an email at all, for example.
I was always under the impression that 409 would be the "correct" code here, while you'd use 400 if the API user didn't supply an email at all, for example.
No user cares whether an error response came back with a 400 or a 409 status, or what those codes even mean. It's madness that as a profession we spend so much of our employers' time and money on trivial things that deliver no value whatsoever. Response codes, HTTP verbs and pretty hierarchical URLs are all meaningless. I've lost count of the number of meetings I've been in where there have been pointless, timewasting debates about these things. Should we expose separate /foos and /bars endpoints? Should it be /foos/{foo_id}/bars/{bar_id}? Or maybe both? Do we need a POST, a PUT or a PATCH? Etc, ad nauseam.
I'm generally cautious when it comes to embracing new technologies, but I've wholeheartedly embraced GraphQL simply because it has removed countless hours of unproductive bikeshedding from my professional life.
Unless your product is itself an API, your users shouldn't be exposed to its status codes. Sorry for dispensing trite advice, but you should really have a nice client between API and users, that can translate the difference between 400 and 409 statuses in a comprehensible and friendly way. :)
In my experience, in any situation where you produce an API where you want the client to pay close attention to the actual error that occurred, the list of official HTTP response codes is generally woefully inadequate for the task and you're going to want to work with something much more specific.
If my payment processor is telling me they're declining a transaction because the customer failed a fraud check, I'd rather they didn't communicate that to me with some random 4xx code one of their devs found on a Wikipedia article and tried to bend into shape. Rather, I'd hope the importance of the situation would lead them to compile a table of custom error codes that I can implement properly in my program's logic.
Won't you just send up in those huge discussions you waste so much time on?
That doesn't mean I wouldn't also use the best practices codes for authentication vs authorization etc. I say this loosely though because best practices are really just that. It's more important to maintain a level of consistency within your team or organization so you're all speaking the same language. It's nice to have a starting point like rest APIs (or something that resembles them) so you're not writing a completely new rulebook on standard stuff that other people have already figured out, you can focus more on the problems your team is trying to solve. Why not use a 409 when there's a conflict? Someone already solved that problem. You can still return whatever pretty error message you want.
By ignoring existing standards and re-inventing the wheel with custom errors the previous development team made the system harder to maintain & harder to onboard.
4xx codes are processing errors, or application-level refusals.
I end up borrowing 422 from WebDAV for a generic "Unprocessable Entity", with an error code (for API interpretation/reference lookup) and description (for user display, when appropriate) in the response body.
That said, some of the practices (like being overly clever with status codes) are pointless while others are actually helpful design patterns.
Using nouns over verbs helps you fully think through the process of mutating state in a RESTful/stateless way. The HTTP verbs all have a unique purpose you should understand.
Does it always matter what size of hammer you use? No. That doesn't mean its smart to use a screwdriver as a chisel.
It is a bad engineering idea to reuse HTTP codes that can be thrown by multiple intermediaries confusing the client code.
maybe I'll investigate graphql a bit more, I've just heard it was really complicated to implement the resolvers for the queries so people weren't using them yet.
The ambiguity is probably why most people just use 400 and call it a day.