10 ms·
I deal with REST zealots like this everyday :( just the fact that people spend so much time debating what is and what isn't REST should be a red flag that maybe
by pixie_ 11y ago
I deal with REST zealots like this everyday :( just the fact that people spend so much time debating what is and what isn't REST should be a red flag that maybe it isn't the answer to everything.
All the simple REST examples make it look like it is the perfect solution for CRUD tasks. But in reality API endpoints are not a straight pass through to the database. An endpoint may do any combination of CRUD tasks, it can't be type casted as a single one with a HTTP verb.
Overloading HTTP error codes is another interesting problem. If the server returns 404 for a resource, what actually happened? Did the web server or my application return the 404. Conflating HTTP and application error codes leads to confusion.
HATEOAS is just superfluous. I've met zealots who will defend it to the death. I just haven't found a practical use for it.
Surface area and complexity are a big deal. REST encourages creating a CRUD interface for every single resource. I've met people who have created literally 100 endpoints upfront for a small application - how is that maintainable?
I like that Facebook is standing up to the zealots. I get attacked at work when I try to create simple API endpoints and they aren't 100% REST (if anyone could agree what that even is.)
- sbov 11y agoI agree with pretty much all of this. We developed an API because we had desktop/mobile/website. They all use the same API. I call it REST-ish. I can't see how people think returning 404 for a "this product doesn't exist" is defensible. You now have two different things intertwined: this product doesn't exist (generally not a huge deal - what if an end user manually edits the url on your storefront?), and this url makes no sense (a huge deal - something is broken). If you had code that threw the same exception when a product didn't exist vs when the table in your database doesn't even exist you would be ostracized. I don't see how it's somehow OK because it's REST.
- neilellis 11y agoHTTP error codes are something of an embarrassment to the web. We have more codes for April Fools jokes than some of our most common situations we deal with. We have some bizarrely specific codes like Payment Required and Requested Range Not Satisfiable yet almost all real world application responses get dumped into 400, 500 and a few other codes. How about more specific and useful codes like: Parameter not Supplied, Parameter Name Invalid, Parameter Value Invalid, Url Path Invalid Format, Could Not Parse Data etc. etc. This would also allow client libraries to decide better on how to process errors (i.e. as application or systemic errors). I'm sure folk have better suggestions than I but I can't imagine many folk genuinely feel these existing codes are expressive for the modern (API centric) web.
- joshstrange 11y agoAgreed, the codes are a crap-shoot. We are working on a redesign of our API and I've pushed for always returning a 200 with a defined JSON structure of something along the lines of: { "status": true "data": { ... } } for success and { "status": false "errorCode": 123, "errorMessage": " ... " //Only shown in dev/debug mode } for failures. We haven't nailed it all down yet but there was no way I was going to do HTTP status codes for some things and some JSON errorCodes for others. It needed to be all or nothing and since HTTP codes obviously wouldn't satisfy it was 200's everywhere...
- RussianCow 11y agoThis is what we do as well. As an added bonus, it makes writing client libraries for our API easier since error handling is more consistent. (Many HTTP libraries handle error status codes differently than 200s, which is annoying since you now have to handle errors in two places.)
- neilellis 11y agoI think for application status codes it makes sense to always return 200 and do as you have done. Of course, if your API has received bad data then better to return a 400 and a similar payload. And if your application has caught an exception which is not part of any form of validation then better to return 500 and the payload. Got to do the best we can with the hand we're dealt hey!
- harryf 11y ago> I can't see how people think returning 404 for a "this product doesn't exist" is defensible. To tell Google for example to stop sending traffic to this URL because it's gone.
- sbov 11y agoIs this a thing? Having Google index your REST api?
- RussianCow 11y agoWhich isn't relevant with regards to APIs.
- dragonwriter 11y ago> I can't see how people think returning 404 for a "this product doesn't exist" is defensible. Because that fits perfectly the definition of a 404. > You now have two different things intertwined: this product doesn't exist (generally not a huge deal - what if an end user manually edits the url on your storefront?), and this url makes no sense (a huge deal - something is broken). Arguably, the "this URL makes no sense" case is a better fit for a 400 [0] rather than a 404 [1], so those two cases need not be conflated even when using a 404 for the "this product doesn't exist" case. [0]: "The 400 (Bad Request) status code indicates that the server cannot or will not process the request due to something that is perceived to be a client error (e.g., malformed request syntax, invalid request message framing, or deceptive request routing)." [1] "The 404 (Not Found) status code indicates that the origin server did not find a current representation for the target resource or is not willing to disclose that one exists."
- maratd 11y ago> Overloading HTTP error codes is another interesting problem. If the server returns 404 for a resource, what actually happened? I, the dude who made the API, sent you a 404. I sent you a 404 because that's all I wanted you to know. What actually happened is none of your business. If I wanted you to know, I would have sent a 400 with an explanation attached. But I didn't. Because in this particular case, it was none of your business. 404. > REST encourages creating a CRUD interface for every single resource. I've met people who have created literally 100 endpoints upfront for a small application - how is that maintainable? Why are you making your endpoints by hand? Use a framework where you can define models for your resources and have the framework create everything automatically. If you do need unique code for each of those models ... you don't have a small application on your hands. > I like that Facebook is standing up to the zealots. Are they, though? Or are they baking something that is uniquely suited to their own needs?
- s73v3r 11y ago"I, the dude who made the API, sent you a 404. I sent you a 404 because that's all I wanted you to know. What actually happened is none of your business." As an engineer working for the same company, I very much want to know, because I want to know if I did something wrong on my end, or if something is broken on your end.
- maratd 11y agoEven an internal API should be designed with the same principles as an external one, because through security error, it may end up being exposed. When designing an API, certain conditions must return a 404 with no further explanation given. These are purely security concerns. If you try to login with an email and a password, I will return a 404 with no further explanation if the auth request fails. Even if the email exists in the system. This will prevent abuse of the login mechanism to confirm what emails are valid and which are not. The same principle applies for other resources. On the other hand, if you truly send a malformed request and explaining to you in what way it is malformed poses no security risk ... only a jackass would return a 404. I would send a 400 with a detailed explanation, so that you can fix it.
- qyv 11y agoIn a lot of ways I think what you are saying is actually in line with what the article is saying: Most people don't actually understand REST and it is leading to a lot of poorly designed API's. Unfortunately, the zealots are often the worst offenders in propagating the misunderstandings. For instance: > Surface area and complexity are a big deal. REST encourages creating a CRUD interface for every single resource. I've met people who have created literally 100 endpoints upfront for a small application - how is that maintainable? I disagree, REST does NOT encourage a CRUD interface for every single SERVER SIDE resource. Your rest resources should be modelled after the resources your CLIENT needs. You should not be designing your client resource models based on the underlying server models regardless of using REST, SOAP or some kind of roll-your-own system.
- pixie_ 11y agoIt does encourage more endpoints because I can't include data from two different objects in a response. They should be GET separately. With highly relational data where I need to create an endpoint that returns information regarding 50 different object types, how should I do that? My rolled up response is no longer REST. When I need to act on that data and call an API that can do a variety of CRUD operations to 50 different objects types, how should I do that in a REST way? It leads to developers creating a multitude of APIs to interact with those 50 different object types. Just so they can say their API is REST. For someone trying to use the API it's a nightmare.
- sergiosgc 11y agoNonsense. A URL is a resource endpoint. If a resource is a composition of other resources, it is perfectly acceptable to return all composed resources. Let's try an example: A shopping application, with customers, products and orders. An order composes a customer and all products that were ordered. You'd have endpoints for retrieving a customer (/customer/<id>/), a product (/product/<id>/) and an order (/order/<id>/). When retrieving the order, nothing in REST prohibits you from returning full information about the user and about the products. Now, advancing the discussion, the reverse complaint is that it is wasteful returning a full information complement when GETting an order. Easy peasy. Just use proper mime types and an Accepts header. Pass in "Accepts: application/json+order+deep" or "Accepts: application/json+order+plain" from the client side signaling the kind of response you want from the server.
- wonkaWonka 11y agoI too, am annoyed by those that harp on about /noun/verb ordering and semantics for RESTful URLs. I bite my thumb at them. But REST is really dead simple awesomeness, when it fits into the activities you're trying to support. Reading blog articles, forum posts. Sure, why wouldn't you? Complex analytics joins that converge NOSQL data and cc payment identities over time, for advertisers. No. Not for that. Abortions for some, tiny flags for others!
- jaaron 11y agoThe point of the article is that REST, as originally described, DOES NOT encourage creating a CRUD interface for every single resource. That's very typical for the simplistic Rails-style of REST, but that's not the original intent. And that's just the point and why those of us who care about web-friendly API design get a bit "zealous." Imagine, if you will, that someone's complete argument about the pros and cons of JavaScript were based on pre-node, hell, pre-JQuery use cases. Wouldn't you expect some developers to be a bit upset that you're mischaracterizing an entire programming language? Keep in mind, a lot of what REST is known for today came to pass as a backlash against XML-deathstar-style architectural designs for web services over 10 years ago. At the time, plenty of folks were simply porting ideas and designs from CORBA-style RPC architectures over to the web. While this is possible, you lose all sorts of advantages of an internet-centric design. And that's really what REST is about: designing applications that work with the web, not against it.
- herge 11y ago> REST encourages creating a CRUD interface for every single resource. But it doesn't enforce it. You can always limit a resource to just GET. The joy of REST is that if you later need to 'crudify' a resource later on, you can add the necessary verbs on whichever resource you want.
- tveita 11y agoHATEOAS-y design gives you a great deal of flexibility in how you structure your server side without that complexity bleeding into to the client. E.g., by using full URLs throughout your API, your client doesn't need to care whether it's getting info from "http://example.org/item/23" http://example.org/item/23" or "https://cdn.example.com/aonteuh/d81c7d65-1352-48f0-97fd-dc1c80c437d5.json?logid=user5" https://cdn.example.com/aonteuh/d81c7d65-1352-48f0-97fd-dc1c... Imagine if image tags in HTML were just "<img imgid='23'>" and the browser knew to look them up at "http://example.org/images/23" http://example.org/images/23". You could make a functioning web site with that, but it would limit the things you could do, and maybe even the way you thought about linking. That being said, there are almost always things you can do "better" by constructing the URLs in the client, like reducing response size, and fetching multiple items in a request. It's a trade-off, and I'd be wary of a 'REST enthusiast' who didn't acknowledge that. It could mean that they don't have enough real-world experience to have encountered the rough spots.
- dragonwriter 11y ago> I deal with REST zealots like this everyday :( just the fact that people spend so much time debating what is and what isn't REST should be a red flag that maybe it isn't the answer to everything. REST isn't the answer to everything, to be sure -- but its actually not the REST zealots who pretend it is. Rather, its the opposite: the people who pretend that REST is the answer to everything are the people who just throw around the label "REST" willy-nilly on whatever solution they've come up with to whatever problem they are dealing with. REST zealots are generally fine with people offering solutions that aren't REST, especially for problems for which REST isn't a particularly ideal solution; what they object to is people claiming something is REST that isn't, which interferes with the ability of people to understand what REST is and what its good for, or to even understand what is being proposed. > Overloading HTTP error codes is another interesting problem. If the server returns 404 for a resource, what actually happened? A consumer really shouldn't, in the normal case, care what generated the error code, they should care what the error code means. 404 means the requested resource didn't exist. What component of the system processing the request made that decision shouldn't matter to the consumer (and may indeed change without any change to the meaning because of implementation changes.) The people responsible for the implementation of the system returning the status code certainly care, and should have sufficient logging detail to support that. In any case, HTTP/1.1 specifies [0] for 4xx series errors that "Except when responding to a HEAD request, the server SHOULD send a representation containing an explanation of the error situation, and whether it is a temporary or permanent condition." So, any implementation following the standard will, unless there is a good reason not to, provide an explanation of the error with the 404 response, so to the extent that there is further information that a consumer needs to understand, it should be provided. > HATEOAS is just superfluous. I've met zealots who will defend it to the death. I just haven't found a practical use for it. Have you used a web browser? If you have, and you understand how they work, you should be able to think of a practical use for HATEOAS. If its not applicable to your problem, that's fine to, just don't call whatever solution you cook up REST, because it isn't. > REST encourages creating a CRUD interface for every single resource. No, it doesn't. > I've met people who have created literally 100 endpoints upfront for a small application - how is that maintainable? Probably moreso than an application that puts 100 unrelated pieces of functionality into the same endpoint. Now, if there was too much functionality implemented for the problem, that's not REST's fault, which really addresses how you organize functionality, not what functionality you provide. [0] http://tools.ietf.org/html/rfc7231#section-6.5 http://tools.ietf.org/html/rfc7231#section-6.5
- bmn_ 11y ago> people spend so much time debating what is and what isn't REST should be a red flag that maybe it isn't the answer to everything Does not follow. People spend so much time debating what is and what isn't REST because there are a great number of people who do not understand the topic, have no actual interest in learning it properly, and then come to wrong conclusions and start making wildly inaccurate arguments. Not all Web application problems can be cleanly modelled over REST, so indeed it is not the asnwer to everything, but most can. For those that can, using the REST architectural style is more advantageous than, let's say, remote-procedure calling. > All the simple REST examples make it look like it is the perfect solution for CRUD tasks. All the simple REST examples are written by those ignorants I mentioned above. The simple CRUD model falls apart when there is just a little more complication involved. REST does not mean just CRUD, as any decent REST book teaches. > If the server returns 404 for a resource, what actually happened? Did the web server or my application return the 404. ⁇ If the server returned 404, the server returned 404. This means the client application/the user agent made a mistake, indicated by the leading digit 4. > Conflating HTTP and application error codes leads to confusion. When following REST, that conflating is actually a good practice. Not doing so means tunnelling a proprietary, possibly ad-hoc protocol over HTTP, resulting in non-interoperability. There is no need for any confusion, the response body can deliver a precise problem description applicable to the concrete error condition, perhaps even giving an indication how to fix the problem. There is a wealth of status codes <https://github.com/for-GET/know-your-http-well/blob/master/status-codes.md> https://github.com/for-GET/know-your-http-well/blob/master/s... and many of them semantically map to typical application error states, and it's okay to fall back to generic codes like 422 or 400. > HATEOAS is just superfluous. […] I just haven't found a practical use for it. You need to bring a better argument to the table. Establishing relations between and traversing resources using links and other hypermedia controls is central to the REST architectural style. Every Web browser does this, for timbl's sake! > REST encourages creating a CRUD interface for every single resource. Not true. Nothing in REST encourages this. It's the software architect's fault if there are 100 (supposedly underutilised) resources, not the fault of the architectural style.
- kisstheblade 11y ago> ⁇ If the server returned 404, the server returned 404. This means the client application/the user agent made a mistake, indicated by the leading digit 4. Or the endpoint wasn't configured properly even though the client had the right address. Happens often when developing, maybe another developer changed the endpoint url? Or in production some endpoint hasn't started. (yes this problem is seldom a problem in production or you usually know from other things that the problem is at the server, annoying still) I've had problems with not knowing if 404 is "person not found" type error or "endpoint address is plain wrong" "Bad Request" doesn't describe the situation either very well, I've used it myself to eg. signal missing mandatory parameters. But just using eg. the code 200 as someone suggested and returning your own status message seems a little bit overkill.
- tyrion 11y ago> HATEOAS is just superfluous. I've met zealots who will defend it to the death. I just haven't found a practical use for it. This is really funny. Are you sure you could not spot a practical use of HATEOAS? Like for example every website that lets you navigate through it using web links, without having you to edit the url by hand! Not talking about APIs here, as most of the JSON APIs are indeed not HATEOAS, because JSON has no built in support for hypermedia. But most of the internet's web sites that use HTML also use HATEOAS, so IMHO it seems a little bit pretentious to say that HATEOAS is "just superfluous :)
- dkersten 11y agoHATEOAS I love the idea of HATEOAS, but in the end, I've never found I cared enough to jump through the hoops of using it (ie it didn't offer enough value for the work it would take), which in turn meant that the effort of implementing it on the server seemed too expensive too.