9 ms·
I know it's not technically correct, but the conceptual definition I've found useful for myself is that REST is about operating on the HTTP layer instead of bui
by lazulicurio 8y ago
I know it's not technically correct, but the conceptual definition I've found useful for myself is that REST is about operating on the HTTP layer instead of building your own layers on top of it. Why create your own custom error protocol when you can use HTTP error codes? Why develop your own caching strategy when you can use HTTP caching? Why create your own authentication mechanism when you can use HTTP authentication over TLS (or client certificates, or etc.)? When the article talks about how REST should be layered, cacheable, and client-agnostic, that's really the core of it to me.
By thinking this way, you can see how REST helps you re-use already-existing infrastructure---proxies, load balancers, caches, etc.---instead of spending time and effort making custom solutions. It also helps provide guidance as to when REST may not be appropriate: can you answer those "why not HTTP?" questions?
I've also found focusing on the resource/noun aspect (beyond considering caching) to be a bit of a "nerd trap"; it's possible to spend a lot of time chasing the perfect, "correct", solution. As the article notes, there's nothing wrong with "verby" URLs as long as you are using HTTP instead of doing your own thing.
- osrec 8y agoWhile I agree that we should not reinvent the wheel, caching data is often tricky with REST. In my experience, the caching aspect of HTTP can introduce unexpected behaviour into applications. To get round this, I see a lot of devs use POST requests for everything, and implement their own custom caching layer. Basically, I think HTTP caching is fine for files, but once you start working with complex data, things get cumbersome rather quickly.
- cxmnvcxkldn 8y agoWhat the actual problem with caching is, is personalisation. This has nothig to do with REST.
- organsnyder 8y agoFor caching to work, you need to sit down—ideally with business stakeholders—and decide what the caching policy should be for each data element. For instance, in a healthcare domain, your core patient demographics—name, DOB, ethnicity, gender...—can likely have a fairly long TTL (perhaps even a day or more), since those attributes don't tend to change very often. However, something like a patient's list of upcoming appointments should have a very short TTL, since it changes more frequently. Once you've made those decisions from a business perspective, you can have your services send the HTTP headers to effect that caching behavior.
- xyzzy123 8y agoExcept for regulatory reasons you will not be able to cache any of those fields you mentioned using standard HTTP infrastructure... You also probably should not let the browser cache it either (you’ll typically get dinged for it in pentests because your app may be used on a shared computer).
- organsnyder 8y agoYou may not be able to present cacheable data to your end-users, but you can still utilize caching for internal consumers (such as application-layer services consuming data from enterprise-layer services). Or, if you have a CDN, you could cache closer to the end-user (assuming you have the necessary controls on your CDN to meet regulatory [and common-sense] requirements).
- xyzzy123 8y agoYep, caching in generally totally makes sense where possible and agree re: services and CDNs. But end-to-end cacheability at the HTTP layer, part of the original rationale behind the REST API design style, does not make sense for most APIs anymore in 2018.
- mwcampbell 8y ago> But end-to-end cacheability at the HTTP layer, part of the original rationale behind the REST API design style, does not make sense for most APIs anymore in 2018. Why not? What were the relevant changes between the 90s and 2018?
- xyzzy123 8y ago* Most APIs are authenticated. * HTTPS has broken intermediate caches. * Most responses are personalised or highly dynamic. * Many responses contain PII or sensitive information and should not be cached. * Many requests are rate-limited, billed or metered. Observation: people go out of their way to cache static resources but tend to disable caching entirely on their JSON APIs. I do have some bias; recovering pentester who rarely worked with APIs that served the same response to all users.
- crdoconnor 8y ago>I've also found focusing on the resource/noun aspect (beyond considering caching) to be a bit of a "nerd trap"; Agree when it comes to the difference between POST/DELETE/PUT/etc. but almost every time I've seen somebody doing a GET which mutated state somehow, the people doing it were always dismissive of the importance of adhering to HTTP semantics and it always inevitably came back to bite us in some way. It was sometimes caching related but there are a lot more things that can go wrong than just that. Using POST where GET should have been used hasn't caused horrendous bugs in the same way, but it still introduces annoyances.
- yxhuvud 8y agoA related issue is the people that see a one to one relationship between the endpoints and the database records that is exposed through the endpoints. As opposed to exposing the business actions through resources and not be dependant on the underlying representation.
- mrec 8y ago> Using POST where GET should have been used hasn't caused horrendous bugs in the same way, but it still introduces annoyances. In my experience, "using POST where GET should have been used" is normally a consequence of URL length limits and HTTP not supporting request bodies for GET. I've never understood the latter decision.
- deleted 8y ago[deleted]
- masklinn 8y agoNone of this has anything to do with REST. You can do RPC over HTTP and do all those just fine, that's just called being a good HTTP citizen. REST is about hypertext-driving[0] and essentially nothing else. [0] https://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven https://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypert...
- lucideer 8y agoThat link is a great representation of why the term "REST" is so often misused; the author's language is opaque and he makes no attempt to make his thesis accessible to readers. He speaks entirely in abstractions and generalities; nothing is grounded in familiar terminology. The very first comment from that post asks what he means by "hypertext", a fairly fundamental prerequisite for following his thesis. He replies with the following: > Hypertext has many definitions > When I say hypertext, I mean the simultaneous presentation of information and controls such that the information becomes the affordance through which the user (or automaton) obtains choices and selects actions I challenge anyone to transform something as simple as "hypertext is text with links to other text in it" into a more convoluted and unnecessarily abstracted definition as the above.
- pfortuny 8y agoIt is because he seems to be thinking of hypertext as html (i.e. he is mixing the concept “hypertext” with the language “html” used to realize the concept (and much more)).
- vfc1 8y agoUnfortunately, that is typical of academic texts, where that embellishment is expected, if not almost mandatory for the whole thing to be approved by the jury.
- lucideer 8y agoWhile it's certainly true of quite a few academic texts, I've read quite a lot for which it's not the case. I don't think it's mandatory, particularly for jury approval, rather just a quirk of many academic individuals. Moreover, this is blog post and comments on a blog post: academic juries aren't the intended audience.
- _pmf_ 8y ago> I've found useful for myself is that REST is about operating on the HTTP layer instead of building your own layers on top of it That's just using HTTP.
- peterwwillis 8y agoI think people are missing the parent's point. HTTP is not just some random aspect of delivering your content. It's an integral architectural aspect of the service. If you're doing caching, you want to do that throughout the network (via proxy) so you can have tiered control of traffic flow. If you're going to block access to networks, you want to do that at a firewall so you can do some access control independent of your API endpoints. If you're designing your API, you want your HTTP method to reflect the kind of operation happening on the server, so you can categorize traffic by method when you're looking at service metrics. These aren't just "using HTTP well", they're deep architectural decisions. They deal with HTTP, but you make them not just because you're trying to use some transport protocol the right way, but because it improves your quality of service.
- wyuenho 8y ago> Why create your own custom error protocol when you can use HTTP error codes? Because HTTP error codes are fixed and have well-defined meanings for HTTP that may not map well to your application. Repurposing HTTP error codes conflates your application-specific errors unless it maps to an exact subset of one of the predefined errors. > Why create your own authentication mechanism when you can use HTTP authentication over TLS (or client certificates, or etc.)? Do you have a client cert? I've never encountered any server that supports client certs in my entire 15-year career. Also, TLS is not a part of HTTP and HTTP only supported Basic Auth until fairly recently.
- stickfigure 8y agoRepurposing HTTP error codes conflates your application-specific errors unless it maps to an exact subset of one of the predefined errors. ...and beware even the errors that match exactly! I've seen multiple systems in the wild that treat 404 as an application-specific error for "content not found". It sounds perfectly reasonable at first, but it puts you one misconfigured reverse proxy away from inadvertently broadcasting to the world that all your content is gone. This can have data-corrupting effects. If an external system deletes resources via a reliable message queue and treats 404 as a success condition, they run the risk of dropping these messages and creating an inconsistent state. I've seen it happen. Keep application-specific error messages distinguishable from the 'plumbing'.
- wyuenho 8y agoSo.much.experience and wisdom in this answer. I learned something new today. Thank you.
- zilian 8y agoIf it's put in a message queue, use a 202 Accepted somewhere, if it's added with HTTP requests ? 201 Deleted only if deleted in real-time. Then check later for proper deletion on or push status of the job to the consumer. 404 as a success condition does not seem to be reliable to me
- cimmanom 8y ago
- deleted 8y ago[deleted]
- geocar 8y agoI think it's a fine definition, because it really highlights the problems with REST: The HTTP layer is a very popular place to build applications, but it's fraught with problems and underspecification (or an impossibly large number of poor implementations: take your pick). The number of TLS guides that recommend ignoring server certificates, or don't check CRL, or don't check certificate-transparency, or don't log and whitelist changes to the public key -- seem to have no end. In the banking Enterprise, getting whitelisted on the HTTP proxy is infinitely harder than getting a port open. And so on. If you control the client, then there's absolutely no reason to use HTTP: Getting security, reliability, and redundancy on HTTP is extremely complicated, to which end I recommend people simply don't use it: Pre-shared certificates and smart clients are much easier to get right. You wan't caching? Specify and implement the strategy yourself (ideally using content caching instead of timestamps or some arbitrary tag). If you don't control the client, treating HTTP as a tunnel for a protocol with pre-shared certificates and smart client (e.g. OAUTH1a instead of OAUTH2) is still better. You wan't caching? Assume cache-infinity and build cache-busting into the protocol. HTTP clients will lie about the correctness of their caching strategy often enough to spoil any benefit a "browser-side" cache might bring. And REST? My advice to developers is to ignore it. When you say "why develop your own caching strategy", I say, because you have to anyway, otherwise you're leaving clients in the dust. Why implement authentication? Because you have to anyway: Passwords/basic authentication are insecure, and everything else requires so much attention that you don't want decades of deformities around HTTP implementations getting in the way. Error protocols? The error protocol is how you deal with it: Do you retry? Pause and let the user fix something? Alert the operator? HTTP proxies are notorious for modifying error codes so no matter how hard you try to signal in the HTTP stream, you're still in for pain.
- geezerjay 8y ago> If you control the client, then there's absolutely no reason to use HTTP: What about ensuring that your desired ports are opened and your connection won't be eaten by a random firewall because you happened to pick a closed port and the user doesn't want to be bothered with firewalls and your application suddenly is crap because it can't even get its network connection to work when every other alternative works out of the box?
- breadAndWater 8y agoI've also found focusing on the resource/noun aspect ( ... ) to be a bit of a "nerd trap"; Oh, absolutely. Ten years ago, during one of my first projects involving a REST implementation, I was working with a person who I deemed fairly rational, and reasonable to work with. Coding up the REST paths was a breeze, and I had implemented like 99% of perhaps a month's worth of work in under a week. I laid out some quick docs for how to interact with the URL patterns and, proud of how quickly the whole thing snapped into place, I showed it to the guy. He immediately jumped all over me, complaining loudly that the URLs "were not RESTful!!!" Which, of course, shocked me. Was he joking? Certainly not. This was a very serious error. Well, okay! Big deal! So I spent 15 or 20 minutes performing search and replace, changing words from things like: /blue/104 /read/9008 /fetch/18 To things like: /car/104 /book/9008 /page/18 And wowee, crisis averted. I was still weeks ahead of schedule, and the commit was all of 10 minutes ruminating over preferable synonyms to please the sensibilities of humans, rather than struggle with computational correctness. During this time, I briefly mulled over the idea of trolling him with a many-to-many look-up table, and introducing variable synonyms that include opaque MD5 hashes of my original path names, and produce the same effective resource, such as: /48d6215903dff56238e52e8891380c8f/104 /ecae13117d6f0584c25a9da6c8f8415e/9008 /5374034a40c8d6800cb4f449c2ea00a0/18 ...but I otherwise enjoyed working with him, and didn't want to make enemies. The pedantry and neurosis some people raise over obsessive semantics is painful to behold.
- wwweston 8y agoIf you take the "two hard problems in computer science" quote seriously -- or if you simply consider that humans are part of the system -- then naming issues probably deserve careful attention. Then again, if humans are part of the system, it's also probably a good idea to use more reserve with coworkers than "jumping all over me" implies.
- adrianmalacoda 8y agoI don't think your pedantic coworker's criticism is unreasonable at all. APIs, HTTP or otherwise, should communicate what they actually do as best as possible. I have no idea what "blue" is supposed to mean in context, and I struggled to connect "blue" to "car." What the article is saying, and what I think GP is saying, is that trying to model (non-CRUD) actions as "resources" in the pursuit of being "correct REST" is often a waste of time. `/nouns/8000/verb` is somewhat obvious to me (it does `verb` to `noun` 8000) despite not being "proper REST" whereas `/verb/8000` doesn't (what exactly am I `verb`'ing?), `/green/8000` would just make me scratch my head, and `/9f27410725ab8cc8854a2769c7a516b8/8000` tells me I'm wasting my time with this API and should go do something else. As a user or developer I think being obvious and usable is more important than being "correct REST" and so I don't even use the term anymore, I just say HTTP API. You might think it is just "pedantry" or "semantics" but consider that you are not the only one who will be using or reading these APIs, and design accordingly. (However, if your coworker really was jumping up and screaming loudly at you because of this, this suggests he may not be as enjoyable to work with as you think)
- karmakaze 8y agoI'm mostly comfortable with designing not-the-worst REST-inspired APIs when it comes to paths, query params and post/put/returned bodies. Where I do have trouble is specifically with error codes. There never seems to be the right one. Returning any frequency of 5xx error codes could give any load-balancer a reason to remove the instance and replace it. Returning far too many 400 codes makes many errors difficult to distinguish and often the cause is shared between the client and server and could succeed later, so would be inappropriate. The main source of difficulty is where codes describe conditions rather than subsequent actions. It's better to think of 429 as the client shouldn't reissue the same request without backoff. This handles both rate-limited requests as well as a server being overloaded. In this case all is well. Status 400 tells the client not to reissue the same query--it's not clear if that only refers to the lexical structure of the query/body or also the server state, in which case 409 may make more sense. I don't have a clear understanding of what other codes mean to clients or servers. When should one use 410 Gone: "The 410 response is primarily intended to assist the task of web maintenance by notifying the recipient that the resource is intentionally unavailable and that the server owners desire that remote links to that resource be removed." These codes were created for HTML and not REST in mind so we'll have to make do, but don't think they're complete or perfect as-is. New status codes keep getting created with varying adoption.