130
arunnalla
13d

It's super annoying when APIs return 200 and then in response body say

{
"success": false
}

Please stop this annoying pattern. Throw the damn 400 error code for bad requests

Comments
  • 38
    On the other hand, the API I've built responds with appropriate error codes like 406, 400, etc according to the issue, and the team working on the front-end mobile app is asking me to fix that as their whole app crashes when even a single erroneous HTTP status code is returned 🤦‍♂️.
  • 23
    @alcatraz627 that’s their problem. If you’re a frontend developer it’s your job to integrate a properly functioning api, wtf
  • 4
    And if it’s somehow impossible to not make frontend crash on error (yea, doubt that) the team should establish a convention that from this day we ignore status codes, everything is 200 and errors are indicated in the body. It’s not your fault either way, managers should establish such convention. So it’s either frontend or managers fault
  • 7
    @alcatraz627 @alcatraz627 what sort of frontend is that 😂 what happens when there is 500 or something because of scale-up times
  • 5
    @arunnalla that’s “the cto forced us to use wrapper that throws an exception when the code is not 200ish and he pathologically can’t admit that he’s wrong” kind of frontend
  • 3
    @alcatraz627

    Most likely they're too dumb to handle requests properly.

    And this is very bad. Like insanely shitty bad.

    As one of many many many examples:

    To treat an gateway timeout like an API error is dangerous, since a gateway timeout means that data WAS sent to the API, but at some point the connection was closed because it took too long.

    When you've non transactional APIs, this can lead to a whole lot of fun (data exists which shouldn't exist. :) )

    It's just plain wrong - whateva they're doing.
  • 4
    @alcatraz627 jeubus ... like how about an else with a graceful bit of 'didn't work but we're not going to freak out here'.
  • 2
    ahem ahem devrant ahem ahem
  • 4
    Also returning an empty string when no image, and an object when there is an image in a rant
  • 3
    @frogstair you were involved in documenting the APIs of devRant 😀
  • 3
    @arunnalla yes, but not creating the API, that's on dfox
  • 1
    422 > 400
  • 2
    It's usually a good idea to have some sort of context in your response DTO to separate network/server errors from application exceptions. Should it return a 400 status code? That's a matter of opinion. There should be a documented behavior though, and I have a preference for at least 200/400/500 and get irritated when I have to interrogate the response body for railway branch discrimination.

    {
    "operation": "identity",
    "requestId": "dm9l23a9d2mald2mal9jkd2a",
    "opcode": 0,
    "data": {},
    "errorMessage": "",
    "statusCode": 200
    }
  • 0
    @sk23ll You're not wrong.

    At the same time one of my personal pet peves is "OMG those people did this!?!!? how do they not know!?!?" and I get the feeling that sometimes... people don't tell them in a helpful way.

    Now if you do try to teach them a better way, and they don't listen that's on them 100%.

    But the amount of "omg those guys / some jr." stuff and I hear nothing about teaching them not to do that dumb thing ... makes me wonder.
  • 0
    Looks like youve been working with the slack api?
    They do this and i hate it so fucking much!!!
  • 0
    @alcatraz627 well that’s because their... STUPID
  • 12
    {
    "success": "maybe"
    }
  • 4
    @rutee07 never go quantum.
  • 8
    I once worked with a 3rd party API that returned HTTP:400 on success. FML.
  • 1
    @devphobe Everyone knows that guy at work who no matter what is negative. There it is in API form ;)
  • 0
    @alcatraz627 I can understand your pain, from aast year I have heard many things and complaints you won't believe like no one ever will believe ..
    Like sending wrong inputs, calling wrong APIs , creating missing data
    Asking to add multiple api operations in single api...
    The list goes on and oooonnn 😅😁🙏
  • 2
    @uyouthe Even if they use such a wrapper, they can just catch the exception.

    "It's easier to ask for forgiveness than ask for permission", like in Python. I actually had to use some wrappers like that in Python.

    I also had to deal with a wrapper not recognizing 204 as a valid empty message. It allowed most common 2xx for messages with content, but for no content it allowed only 200... <facepalm>
  • 5
    I have never understood this doctrine.
    There is a difference between HTTP status codes and API errors. It is a different level. When there is an error in the API, like for example there couldn't any values be found, then the HTTP call was nevertheless perfectly fine and should return 200 because there was no error on the HTTP site. The call did work perfectly fine, it was the API itself that had the error.
    One should instead design an API completely seperated from the transport medium. It should make no difference if it is called with HTTP(S), TCP, UDP or smoke signals, the API should behave exactly the same everywhere.
  • 1
    My FE team just request that every response code is 200 but in body response they want like

    {
    code: 400,
    success: false
    }

    It's normal people use or what.?
  • 1
    @sarafe they are super normal people 😂
  • 0
    @Benedikt PureJSON is an attempt at something like what you're describing
  • 0
    not enough people mock apis before actually building them. like starting a new database without even attempting to napkin sketch a schema. But I think thats called nosql these days!
  • 0
    This is one of my absolute pet peeves when api developers do this, it’s not hard to return a 40x just do so!
  • 3
    Controversial opinion: most of the HTTP status codes seem, to me, to be designed to be responses of the protocol (HTTP) itself, not the "layer 7½" web app. You could argue 200 just means "the webserver (not the app, but the load-balancer or reverse proxy) understood your request, and the app at least processed it".
  • 0
    .then(res => ({

    /stuff

    })

    .catch (err => {

    // err

    })

    ... idk it may work
  • 1
    might be an misunderstanding here....

    For me (and my comment) are based on the fact that you have an HTTP based API.

    HTTP is the protocol, as such speak HTTP.

    Many devs fall into the following tar pit:
    - result code: state of HTTP request
    - result response: state of operation

    But when you implement an HTTP API, the state of the operation should be your result code.

    Otherwise, you define your own protocol, which is wrong imho.

    You should always bubble up your error state. When you return the call status instead of the return status, this is not possible anymore. (see next point, please).

    Since the protocol is HTTP and you essentially wrapped the operation status in the response, you need to "materialize" the response before you can bubble up the state.

    What does materialize mean?
    In most cases: Waiting for the full data stream to arrive, and then converting / decoding it.

    Here lies the main reason why this is dangerous: You've to fully parse the response to be able to actually get the operations result.

    This might seem trivial - but is an actual performance and logical problem.

    In most cases, you could - if you encode the operation result as the HTTP result - short wire the action. No decoding, no checking wether result is sane, nothing.

    This technique is essential for everything man in the middle related.

    A loadbalancer, proxy or whatever cannot make any assumptions about your operation result. Even something simple requires decoding the result and parsing it.

    You're essentially redefining HTTP to be response instead of status code based (think about it carefully).
  • 0
    @IntrusionCM yes, but it's a violation of the HTTP rules to not read the response body, and parsing JSON or whatever is trivial compared to waiting for the network
  • 0
    @pxeger violation of HTTP rules...

    Source please, cause afaik this is wrong. Very wrong.

    And what do you mean by waiting for network?

    And parsing isn't trivial. Especially not with JSON.
  • 0
    @pxeger

    https://w3.org/Protocols/rfc2616/...

    "The client is not required to examine or display the Reason- Phrase. "
  • 1
    @IntrusionCM

    1. By "waiting for the network", I meant the reading and writing to network sockets, which is blocking.

    2. JSON parsing is really pretty simple compared to C, HTML, or pretty much anything else. And it is extremely fast compared to the time which is required to process a request while waiting for the network. That's what I meant by trivial - in terms of speed

    3. What you quoted is about the response code reason, which is the `See Other` part in a response line `HTTP/1.1 303 See Other`.

    4. You linked the spec for HTTP 1.0 which is obsolete.

    5. I can't find anything giving evidence either way in the RFCs (7230-7235). But every server and client I've ever worked with treats a prematurely closed connection as a failure, as any sane programmer would.
  • 0
    @pxeger whoops, wrong link.

    https://w3.org/Protocols/rfc2616/...

    It's HTTP 1.1 which is common. Not HTTP 1.0.

    And I think you got me wrong.

    I tried to use the word materializing...

    You will in any case have to wait for a full response.

    But there is a difference wether you need to parse the response to get a result or simple have the status code.

    Http is based on an status code, not on the message that is delivered.

    And decoding the message and converting it is _always_ a performance penalty.
  • 0
    @IntrusionCM yes, JSON does always take time to parse/interpret. But my point is, compared to the time it takes to read the data from the network, it is negligible.

    I suppose you can dispatch the connection continuation to another thread and not do anything with the data, though.

    And you're still linking RFC 2616 which is obsolete. (I got it wrong, that's also for HTTP/1.1 apparently though)
  • 0
    @pxeger

    Second point: Bullseye.

    First point: You're thinking too much about time.

    Performance means more than time... It's about the resources, too. It matters wether you need to evaluate a fixed integer or fully inspect the payload.
  • 0
    @Benedikt What the hell? API is just like any other application behind HTTP - if there is something wrong in the API, then it should respond with 5XX HTTP code. If the user did enter some wrong data into the request, response should be 4XX. That's it.
    If user requests page which isn't there, it should be 404, not 200 as you're implying.
    If you want to design an API which is working regardless of the protocol, then go for it, you can easily return error codes in the response body, but as long as you use HTTP specifically, then you should use it's conventions.
Add Comment