It's also why I raised the issue of where your "server boundary" is. I dunno how else to phrase it, but what I mean is the separation of domain logic and technical logic.
In my understanding, 400 denotes an HTTP request that doesn't comply with the RFC (missing headers, bad format etc) but I also don't disagree with what you're saying, because the user did send a bad request.
Of course, you could always do both :) Send the opinionated payload with a 400 error.
As long as your consumer can reason about what went wrong, then I guess that's in line with the objective I was trying to get across.
I think there is a correct answer: use the 404 to indicate that a requested resource does not exist, and use a 200 to return a requested resource that does exist; and use URLs to represent resources.
In other words, follow the HTTP RFCs.
And never, ever, ever EVER use a 200-series status code to return an error.
5XX - Server did something wrong
4XX - Client system did something wrong
2XX - Everything worked
IMHO, what's missing is a code for "All systems worked but the user did something wrong" for scenarios like looking up a non existent ID or if their CC details don't work.
https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/422
The objective mostly was to try help form a way of reasoning about HTTP APIs from the consumer's perspective
> error 400 for all semantically-invalid requests
Counter point: Passing `a` to the example endpoint is not semantically-invalid from the perspective of HTTP, it's a perfectly valid URL. Nothing about that request is invalid, it's only invalid to the business layer, which has nothing to do with the HTTP layer. Put another way: The server _is_ processing the request, that's how it send back the "employee not found" record. I guess it depends where you want to draw the boundary of server.
Which is not to say you are wrong if you return a 400, but I suspect you might get a couple queries about it from consumers.
The objective was mostly about clarity. Maybe I'm being over-simplistic, but I like the idea of using protocol errors for protocol problems and domain errors for domain problems. Just keeps client-side logic cleaner in my experience