Hacker News new | past | comments | ask | show | jobs | submit login

The problem is most REST services, because they are fundamentally HTTP services, are subject to how the underlying HTTP application server/proxy/middleware handles HTTP requests. Which are valid to return 404 in many more cases than where REST would allow you to return 404. In Targets case, it should have probably returned 400 Bad Client, since what the client tried to access wasn’t a REST endpoint.

The real problem with REST and HTTP is that it’s too easy to put middleware in between that doesn’t understand REST, just HTTP. As a software engineer or architect you can design the API to be perfect to your needs, but, when deployed you often lose control of how the client and server actually connect to each other. Proxies, caches, IDS, WAF, all can get in the way and don’t respect REST semantics.




As someone who tries to steer teams toward designing for middleboxes up front instead of trying to spackle caching into the system once it's too baroque to implement properly, I find that a little time up front avoids a lot of pain and anger later on. 400 bad request is a much better way to signal that there is no REST endpoint for that request versus there is one but we didn't find any data.

Also worrying about cache expiry is often a red herring. It's not fixing a problem, unless the problem is that the Product Owner keeps noticing that our code doesn't actually work as advertised. If you can generate a useful etag for a response, you can add client or middlebox caching any time it becomes useful, or take it away when it doesn't. But if you can't generate a useful etag, then any bespoke caching mechanism you build is unsound, because correct etag and correct cache invalidation are isomorphic.

I'd rather know we're on the road to unsound sooner rather than after customers rely on a bunch of misfeatures.


Do you feel like it's a mistake to conflate URL paths with resources?

Because it sounds like you take issue with the conflation of "404 because user 12345 doesn't exist" and "404 because this url path is malformed", and (if I understand your post) are suggesting that the latter should be 400 so as to allow the former to be 404.

What about instead using 204 to signal "does not exist in database but request is otherwise valid"?


Well I think 404 is only the first problem you have to solve and people don't even do that very well, then declare success and move on. I've seen so many developers try to reinvent things that are in the HTTP 1.0 specification.

I've definitely had to deal with problems of people returning 200 not found and those leaking up into higher layers of the system, and I agree with the people who don't like that solution. 204 is probably better, but I've seen too much code that looks for 200<=status<300 so you're still dealing with the same problem, but at least that's a client bug not a roll your own thing issue.

On one project, I put the kibosh on someone trying to negotiate clock skew detection between the client and server. I don't recall what they were going to do about it but I pointed out that information is already in the request headers, and has been from the start. So if your timing decisions are tied to an HTTP request, you don't need to do anything out of band to negotiate a common notion of time.

I don't recall when I stopped seeing timestamps of January 2, 1970, but I know I saw enough of them that it stopped being a novelty and I stopped looking for them. In 1995 when they were still working on the spec, nobody used NTP yet, and many, many people had a dead or dying CR2032 battery on their motherboard and either hadn't noticed or didn't know where to buy a replacement. The dying ones were the worst because sometimes they would hold the time but not increment it properly, so the clock skew was proportional to how many hours a day they turned the machine off. "Expires on March 1" didn't mean anything, unless you knew that the server thought it was February 28th. I suspect Tim was thinking of time zones between scientists in Switzerland, France, England and Germany, but it worked really well for crap hardware too.


> The real problem with REST and HTTP is that it’s too easy to put middleware in between that doesn’t understand REST, just HTTP.

REST isn't a protocol, but a major point of REST’s direction to use the underlying protocol as specified is that if your are doing REST, middleware doesn't need to understand REST, only the underlying protocol.

And the problem here wasn't middleware that wasn't aware of REST, it was middleware that was misconfigured and requesting data from the wrong remapped URLs and relaying the responses faithfully. There was nothing failing to respect REST semantics involved.


> In Targets case, it should have probably returned 400 Bad Client, since what the client tried to access wasn’t a REST endpoint.

The trouble with that approach is it puts the onus on the Server to response accordingly. In the case of a Client misconfiguration you might point the Client at a valid HTTP Server, just not the one you anticipated.

I agree with nerdponx that they were miss using 404. Instead they should have used a different HTTP Response Status Code to indicate something was removed from the system. Perhaps 410 Gone or 417 Expectation Failed.


417 is specifically for use with the Expect header, so would be a misuse as well. 410 would be fine, but is technically a sub-case of 404, so if 410 is fine 404 should arguably be too.




Consider applying for YC's Spring batch! Applications are open till Feb 11.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: