Two reasons why using 200 instead of 404 can make sense:
- No way to distinguish between the api client calling the wrong URL eg /mytypo/12345 instead of /myquery/12345. With 404, the client will not realise their mistake without debugging.
- Lots of 404 errors can trigger security sensors. Having to whitelist 404 in a security sensor can be a pain to convince the team that manages them. Doubly so if they are part of the other company rather than yours.
Aside from slightly less code to write, what benefit does 404 bring?
With a 200 your client won't know they've done anything wrong without debugging either. There is nothing preventing you from returning a detailed error message with your 404.
If under your suggestion you have to look at the details of a 404 anyway to get a detailed error message, what is the point of the 404? Your client always has to do an explicit check for error/no-error. Why make them check two different locations? Just always look at the body: one location.
If the 404 is due to the client calling the wrong URL, rather than trying to access an entity/record that doesn’t exist, the client code will incorrectly assume the entity/record doesn’t exist when it actually does.
Eg an API has a /discountvoucher/ID, so your client can enter a discount voucher code and get info on the voucher. If your client code calls /voucher/ID instead, under the 404 approach you would incorrectly think the voucher doesn’t exist, when it does.
If using the other approach, you have this code in the body, you would know straight away that the URL itself is wrong because you’d have no JSON body.
So in the former approach the client code would be oblivious to the error until someone realises, maybe years down the track, that the code is calling the wrong URL. In the later approach you would know immediate as the client will receive a body content it’s not expecting and throw a fit.
Yes you could return 404 as the http status code and embed the code into the body, but that brings us back to why do both? That opens up for lazy programmers to just check the first and not the second.
> If the 404 is due to the client calling the wrong URL, rather than trying to access an entity/record that doesn’t exist, the client code will incorrectly assume the entity/record doesn’t exist when it actually does.
There's the root of your error: the entity is the URL; the URL is the entity. If the client requests a URL which does not exist … that URL does not exist.
If the client requested a URL which does not fit the expected schema … that URL does not exist.
Once you embrace RESTfulness & HATEOAS, life gets so much simpler. Also, every time you return errors in a 200, God kills a kitten. If for nothing else, think of the kittens!
Because they can pull extra information out that can help them understand why they're receiving a 404. The lack of information can itself become a signal.
> -No way to distinguish between the api client calling the wrong URL eg /mytypo/12345 instead of /myquery/12345.
More often than not, this distinction matters less than one might think. In either case, you've got an upstream problem for the client: how it's determining the `mytypo` portion of the path or how it's fetching invalid identifiers. This is actually part of the point of the philosophy behind REST.
But if caring about fine distinctions is the point here, there's no appreciable improvement between using 404 for both "something's bad about the path" and "path's good, no resource here" and using 200 for both "path's good, no resource here" and "everything's fine!" Especially when, personally, I think the distinction between "I got back data!" and "I didn't get back data" is more important than "I didn't get back data for reason X" vs "I didn't get back data for reason Y."
Now, maybe you don't agree with that prioritization, or maybe you'd argue "Oh, I just handle did-vs-didn't-get-data situations both under 200 with a message somewhere in the response body." Cool. As my earlier comment points out, you can do that in the response body of a 404 too.
So of course it is quite possible to make distinctions between why a 404 error code happens, just the same as it is for what kind of 200 you're getting back.
And you can still go straight status header on top of that too: make your own 4xx for "resource not found even though URL is correct", maybe something like 434. Or if you're queasy about that sort of improvisation, use 400 with a status message in the body about an invalid id. Or if you're absolutely sure for some reason that it should be 2xx, consider 204 (though it sure seems like a bad id is a form of client error).
> Lots of 404 errors can trigger security sensors. Having to whitelist 404 in a security sensor can be a pain to convince the team that manages them.
I might well have a side-eye for a security team that sets its thresholds here too aggressively, but OTOH, a client that is generating a lot of 404 errors on legit URLs is either broken or it's getting fed bad ids by the API... or it is in fact malicious. In each case eyebrows should be raised. Hopefully any security layer is also sending back a useful status code and response body to the client.
> Aside from slightly less code to write, what benefit does 404 bring?
Like I said in my earlier comment, out-of-band broad status code can let you switch between error handling pathways well before you've spent time parsing a more detailed message in the body (which you may or may not get, depending on the error condition!), or even for specific error messages you have never thought of much less seen. Knowing what kind of error you're dealing with before you know the deep specifics is really useful across a variety of software situations.
And there's so much web tech and tooling that's set up to see 200 as "Everything is Fine, You Got What You Wanted!" You're working against the related infrastructure when you use 200 to indicate an error condition. You're working with it when you use HTTP status codes.
- No way to distinguish between the api client calling the wrong URL eg /mytypo/12345 instead of /myquery/12345. With 404, the client will not realise their mistake without debugging.
- Lots of 404 errors can trigger security sensors. Having to whitelist 404 in a security sensor can be a pain to convince the team that manages them. Doubly so if they are part of the other company rather than yours.
Aside from slightly less code to write, what benefit does 404 bring?