Been having similar case with dev teams who have coded every error to be 500. User typed the wrong URL? 500. User tried to access a page without logging in? 500… Makes detecting real errors a pain
Makes all issues their problem. Clearly it’s not a 4xx error so not something the client did wrong.
And on the other side of this are JS devs that check for neither error response codes or error messages, and write an error into their own data as if it’s the result they were after.
Always fun to see GET /orders/{error : “invalid branchID provided”} in your logs.
I would argue that in your application, a wrong URL is a sever error. That error being improper handling of a client error.
I’m not a web dev, but had a similar problem with a niche compiler I used to develop.
We were pretty good at validating invariants at the mid and back-end. This meant that most user errors got reported as internal errors. Generally, these errors were good enough that users were able to get used to reading them and fix their code.
It was next to impossible to actually get users to file bugs about this. Our internal error messages started with a banner that read “THIS IS A BUG IN <compiler name>. PLEASE REPORT TO <support email address>”. Despite that, whenever we actually got a bug report, it would inevitably start with “I’m pretty sure this isn’t actually a bug in the compiler, but I can’t figure out what I am doing wrong in my code”.
I would argue that in your application, a wrong URL is a sever error. That error being improper handling of a client error.
That’s certainly an unusual take. If you are a backend to HTTP and something throws a completely bogus URL out of left field at you, that’s not by any means a backend error.
I guess your take is that it might be some sort of usability issue or such because if 95% of clients try to hit the same non-existant URL, that probably means there’s some reasonable expectation that you should do something about the URL. However that’s relatively more rare a sort of ‘invalid URL’ scenario. The vast vast majority are some sort of scanners trying bogus crap, followed by an impossibly diverse set of typos and peculiar one-off assumptions that you can’t possibly reasonably cover.
If it’s not a backend error, you shouldn’t be throwing a 5xx error code. Since you are throwing a 500, you have a server bug; even if that bug is simply “sends incorrect error code”
I’d easily take that over ‘200 for everything’. If at least errors are distinct from success, I’d take that as a win. My standards have been lowered by so many ‘200 for everything’ backends…
Oh no… this brings back memories LOL
Fun story close to a decade ago we were attempting to upgrade our batch scheduler called Tidal to version 6x which had a RESTful API.
One of the reasons we dropped the product was because we were getting 200 status codes meanwhile the output was a java dump of an error message.
They were adamant that this was an us problem, no matter how much I tried to explain to them with numerous links explaining to them that if something has a 200 status code that should mean things worked.
They argued that the 200 meant we were hitting the API fine. We would have to write code to read the return for if it was a error or not. I still don’t think they understood how stupid they were, even all these years later.
I have had that argument repeatedly with people. People insisting that HTTP error codes are “transport layer” and it’s “wrong” for an API to hijack them to report “application level issues”.
No, the whole point of “REST” was to map application semantics to HTTP in a way that actually normalizes some things like error handling and expectations around whether an operation could be expected to be idempotent and make the namespace navigable.
At one point my work announced a person who was an external hire to be the ‘API genius’ to set my company straight. He came from a super reputable well known company so of course he just the smart guy to fix our technical mess. He had sent a message saying that he had reviewed the teams API and concluded they were not restful. I had a glimmer of optimism, that someone recognized as authoritative would call the RPC style HTTP usage that always returned 200 and steer toward sanity, or at least honesty. No, his feedback was that was all fine, but REST does not use JSON, REST uses Protobuf, so they need to change to Protobuf to claim to be REST. Of all the what the hell I could have predicted, that one was not in my book…
A real “API Genius” would be complaining that your API doesn’t include HATEOAS, even though I’ve never once seen an API be used in that way, and few of the big tech APIs actually use it even though they call their APIs RESTful.
The number of people talking about REST without having read the wikipedia page is astonishing. Roy Fielding’s dissertation on the subject might be of interest, but that’s from 2000 and absolutely not webscale.
(Edit: /s if that wasn’t immediately obvious)
JSON API almost always means “not REST”. In other words, it works as intended.
how would you return metadata or more detailed error codes?
However you like, REST doesn’t dictate anything there. Just be consistent and use hypermedia.
JSON APIs almost never follow REST because they almost never use JSON as hypertext. Worse, no complete stable hypertext JSON standard exists. There’s JSON-HAL, but it lacks a way to represent resource templates (think HTML’s
<form>).Therefore, with JSON APIs ignoring one of the most basic idea behind REST, why would anyone expect them to follow another idea of REST - consistency?
REST is a deceptively simple concept. Any time you build an HTML website a human can navigate without consulting documentation, you’re doing it better than vast majority of swagger documented corporate APIs.
Fun fact, I actually did implement JSON-HAL and peers wondered why I was putting this “silly _links dictionary member” in there.
I’ll say I’ve seen other REST APIs using json and at least honor the concept of hypermedia, but in a useless way. They’ll have links specified, but even within their API no consistency on what dictionary keys would refer to related resources versus data.
The argument probably goes something like " if you adhere strictly to REST the error codes are all you need" and then metadata can be sent in response headers.
how should a REST API respond to the client sending a URL the ends in a string instead of a numeric ID? like api.social/users/ceeforayteen instead of api.socail/users/11037
Depends on the verb and the application. If the string is valid 200, if it isn’t 400, 404.
I would do a 400 (Bad Request). Then, with varying amounts of detail depending on the scale of the project and the framework capability, the response body would be something like: { “error”:true, “reason”: “validation”, “detail”: “user id should be numeric” }
that’s what i would do too—a JSON response. or is that not what “JSON API” means?
A RESTful service is (usually as of today) a JSON API. They aren’t mutually exclusive things.
There’s no black and white definition there.
However, when someone is creating a RESTful service, they’re stating that they’ll be paying mind to HTTP Verbs and status codes as a fundamental part of their design.
In the original image posted, that dev clearly wasn’t paying mind to the HTTP layer and as such a commenter called it just a “JSON API”, which is the catchall, ugly, Wild West, typical way of doing things (always return 200, errors are in the json).
Once again tho, it’s not black and white. Others can and will disagree and want to be pedantic. I’ve been a professional dev for 35 years, devs love to argue abt this shit.
devs love to argue abt this shit
Devs and standards have a contentious relationship.
If I develop something, I obviously know what works best for me, so I don’t want to be constrained by some dumb standard. If someone else doesn’t follow them and it makes things harder for me, they’re a clueless fuckwit that shouldn’t be allowed near a computer ever again.
Yes, that’s a double standard: I don’t even have a standard when it comes to handling standards.
devs love to argue abt this shit.
Tabs vs spaces comes to mind.
It’s still just another type of ID so you can do lookups on it. Nothing would change. UUIDs are used all the time.
returning a 400 never prevented me from adding more info to the response
I don’t wanna be pedantic but most things we call REST aren’t REST. The original definition of REST is what we typically call HATEOAS. So when you say JAON API almost always means not REST you need to qualify that.
It’s not us, it’s you
It’s us: 5xx
It’s you: 4xx
Aaagh! Getting some random old person flashbacks.
Kids. I r-remember a day… You won’t believe this… I got a 404 error page… It was otherwise a normal 404 page with a normal message on it, but it had a giant ad on it… like “while you’re here, how about you buy this stuff”… It was hell… You’ve got no idea how lucky you kids are with uBlock…
Another favorite is when the API barfs a stacktrace instead of valid JSON.
Yep, I’ve got one of these at work now. Technically, 200 can make sense here if you’re using HTTP as RPC transport, as the server relayed the request to its handler and returned the outcome, but damn if it’s not annoying to actually process the response.
I’ve also seen a lot of devs tie themselves into knots trying to map various execution types to the “semantically correct” HTTP code, but the thing is the abstraction of HTTP is not based around RPC and it’s ultimately a pretty weird fit that we’ve somehow come to view as normal.
Then just return a 500 - Server error. Nice and obscure.
The ability to separate “something wrong with what you sent” (4XX) and “something wrong on the server” (5XX) is very valuable in itself.
Yep
- 2xx - it’s good
- 3xx - not here cunt
- 4xx - you don fucked up
- 5xx - we fucked up, whatever you do aint changing shit.
And then there’s 418
good old 418, always appears when you really want a cup of coffee
The number of times I’ve gotten 5xx codes for bad requests is annoyingly high.
Fair. But they still fucked up so at least that’s on them
I guess it’s like a retail worker apologising excessively because of trauma.
1xx - We’re still working on it
Respond to everything as a teapot
Removed by mod
I’d rather see this than actual rest or the more popular use the bits of rest that are convenient.
you’d rather have no responses following a standard rather than only some doing that? No, thanks.
Yes I’d rather have a self defined standard that accurately covers the scope of an application and it’s use cases than stretch an old standard design for basic hierarchical text docs to work for a modern application.
And what’s inherently new in modern applications? We’re transferring state and operating on resources just like we used to do. Most web apps are variations of CRUD.
Yes most things are crud if you zoom out enough that doesn’t mean REST is just fine. The scope is larger now, the states are more complex and interrelated, relationships are more complex, data privacy laws can affect the physical implementation. REST also has a lot of baggage that leads to excessive bike shedding, or refusal to allow useful endpoints that aren’t sufficiently restful. Proponents also tend to be more concerned with the purity of the api than the usability and effectiveness of it
refusal to allow useful endpoints that aren’t sufficiently restful
And there are good reasons for that, GraphQL-like endpoints seem great to use, but are often a bad idea. The more freedom is given through an API, the less guarantees one can deliver. Security, scalability, and maintainability all become more difficult for APIs with endpoints that attempt to do several things at once.
But most importantly, REST doesn’t tell you exactly how to build your endpoints, as long as they’re stateless, cacheable, and refer to system resources with enough context to allow their direct manipulation.
These are good principles for older and modern web apps, that hasn’t changed. In fact, one can argue that the larger and more complex the system the more important it is to simplify its endpoints. And you can build pretty complex systems while following these criteria.
Fully agree, purity of REST is dubious, but a ‘REST-as-possible’ absolutely is helpful to keep people from going way of the rails in ways that annoy external consumers of their API. One API I dealt with claimed to be ‘REST’ but basically everything you did was ‘Create a Task’, ‘Get Task’. No modeling of state other than the state of remote function calls, which might have been nice for them but now I have to lean what tasks are possible and how to create them when a more REST like hierarchy would have been a bit closer to ‘self documenting’.
This is why I’m not a fan of REST, the whole as possible part is meaningless. It could be an api that’s 99% REST with a few well thought out methods for common actions that aren’t quite REST, or it could be a mess of an api that uses PUT occasionally.
Self documenting at an application api level is not really possible. What I’d rather have is consistency and predictability, which is impossible in a REST as possible system.
Yes, there are certain things that don’t map to key principles of REST, and I have upon occasion see people way too hooked on purity of REST for any practical end.
However, to the extent that you at least consider how it could map, then that’s helpful.
If you say “you can’t have an application error, you must ONLY use HTTP error codes”, that would be bogus. But if your application knows it has an error, why not also set HTTP status code to indicate an error as well? You have to set a status code anyway, might as well at least get the first digit right, or just 500 == error, 200 ==OK if you don’t want to hash out 4XX v. 5XX.
REST may not be sufficient, but that doesn’t mean it’s helpful to actively work against the HTTP semantics when they could be a vague indicator consistent with your API.
There’s also value in treating http as just a transport later. It can give you clear boundaries, 200 the app processed the request, anything else the app didn’t process it.
But what is the value of a 200 OK when the request absolutely failed? As a caller, I don’t care that it successfully was conveyed but still utterly failed. Depending on my usage, I may only care about pass/ fail and the backend insisting I have to handle multiple different ways of expressing failure is just more work with no value.
Using 500 does nothing to preclude your application errors. If the caller wants nuance, it can still have it in the body or headers.
Right? REST is the transport, if you bend it to convey general/application errors it’s probably going to get bent out of shape eventually in a way that’s hard to clean up
The people that decide which rules are important or not when designing a “REST” api are generally insufferable as well.
Marketo my
belovedthe bane of my existence. Actually without a doubt the worst API I’ve ever worked with in my career. The response schemas are random and a 200 means nothing because it might also include a “success”: “false”"error = true with no description or answer is basically ten years of searching stackoverflow and reddit threads for an answer.
Honestly at this point if it’s source available it’s almost faster to dig through and find the affected module on source to determine behavior.
Unless of course it’s just crazy abstracted, which can be an unintentional form of obfuscation when applied poorly.
Or a link to a thread on microsoft answers that 404s
that’s the worst due to how microsoft answers redirects work making it impossible to go back to the previous page.
Congratulations! You failed.
no worries! a small failure is the first step on the way to a really really big failure.
Every time I see someone recommend this at work I die a little inside. Like… C’mon!
















