Hacker News new | ask | show | jobs
by lazulicurio 2899 days 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.

8 comments

None 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-hypert...

That 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.

> 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

What's unclear or abstract about that? To choose an action, the agent must know what actions are available and how to call them. Whatever presents that information to the agent is the affordance. Fielding says that in hyptertext, you get that as part of the actual content as opposed to via documentation or some other channel.

> 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.

Because that's not what it is, in general. See Xanadu for an example of vastly more general kinds of linkages than references.

> Because that's not what it is, in general. See Xanadu for an example of vastly more general kinds of linkages than references.

The purpose of very abstract, generalised, academic (also legal) language is to attempt to achieve perfect technical correctness in description. Unfortunately this usually comes at the cost of understanding.

"Text with links to other text" obviously won't include 100.000% of applications conforming to RESTfulness, but it does describe what RESTfulness intends far better and more accessibly than a convoluted explanation, which very effectively serves the purpose of informing people calling RPC REST that it is not in fact REST (for example). It also gives a broad audience a general direction to work toward if they intend to use REST (or a reasonable argument not to use it if it's not what they feel they need).

The accessible explanation serves an actual practical purpose, the pedantic explanation has no actual benefit. The fact that you had to reference a project as esoteric and dead-end as Xanadu is testament to this.

>What's unclear or abstract about that? To choose an action, the agent must know what actions are available and how to call them. Whatever presents that information to the agent is the affordance. Fielding says that in hyptertext, you get that as part of the actual content as opposed to via documentation or some other channel.

But then that would be wrong. You had to know, through documentation and other out-of-band education, what you’re supposed to do with these `<a href=...` things. Ditto for any of the other options a page might present.

When you first used the web, you didn’t know what href meant. You had to read some instructions, or depend on UX designers’ decision to graphically represent a-tags in a way that suggests clickability and followability. That’s already outside his REST model.

Fielding is not being clear on how REST’s assumptions about “what you already know out-of-band” differ from other models.

> 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.

Except text+links does not encompass the full meaning of hypertext. Forms and inputs are also possible, for instance. The more general definition you cite encompasses all of this (information+controls), and more possible innovations than your very specific definition which lists only the current ways.

That was my exact thought process. No examples, familiar terminology, or simple language: just architectural astronautery par excellence.

I always find myself sceptical of people who appear to hold an almost religious level of belief about some programming construct or protocol and yet are unable to express themselves plainly. It comes off like a developer-ish version of business speak and isn't generally useful for moving a discussion forward or solving any problems.

He's just an academic, using academic language.
some people just love to write with as much big words as possible. i hope they try challenge themselves in the opposite, to use as much common words as possible and see what comes out of them.
It 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)).
Unfortunately, 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.
While 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.

I've basically abandoned the term "REST", because for all X where X is the current topic of conversation, REST is not X.

Any term this confused just isn't useful.

"Monad" seems to be similarly confused, but there's a concrete math concept to fall back on, and concrete definitions in various languages. REST doesn't have that. No matter where I try to stick the pin in the landscape and say "That is REST", I am reliably informed by half-a-dozen people that no, that's not it, it's over there... and I get six different "theres".

(No, the thesis does not define it, in practice. Even when people reference it, they still point to different places! And besides... so a guy sat down and wrote a thesis paper on a word... that's great and very nice for him, and not worthless, but let's not go overestimating how much claim that gives you to a particular word. I certainly don't grant it enough claim to overcome the fact that still nobody knows what it means.)

Useless.

(I've carefully written this to be clear that I'm speaking about the term. Whatever $YOU think REST is may very well have good ideas in it, but labeling it REST only makes things worse.)

> '"Monad" seems to be similarly confused'

In most cases Monad goes the opposite direction than REST: most people discover that yes, what they've been writing is a monad, they just didn't know it. Conversely, most people are told that no, they are not doing REST right, because REST is actually about <something else> ;)

Monad is a scary name for a very simple thing, while REST is a very simple name for something that is probably scary, because I don't think I have ever seen it.
Terminological confusion appears to be our bread and butter these days.

There's large companies calling their MVP "MVC", and then you have to explain that "MVC solves the problems of MVC" (-> real MVC solves the problems of Apple MVC, and is being rediscovered all the time with "unidirectional data flow" of things like React).

And then there's "React", which doesn't actually have anything to do with "Reactive", but has similar enough marketing that you think it might.

Which gets us to the current champion of muddled terminology: "Reactive Programming" or "FRP".

So although the various "reactive" (Rx) approaches are often called "FRP" (Functional Reactive Programming), they actually are not at all the same thing. At least according to the person who came up with FRP and coined the term. Of course, he no longer thinks that was a good name for what he did, preferring "Functional Temporal Programming".

And that's a good point, because as Backus points out (see https://news.ycombinator.com/item?id=17564186), FP doesn't handle time well, and so Functional Temporal Programming tries to address that deficiency.

Does that mean that the others are off the hook in calling their stuff "FRP" or "Reactive"? Nope, as it still doesn't make much sense, "reactive" being a description of systems not of implementation technology, and the implementation technology being a form of (synchronous) dataflow that can be combined with either imperative or functional languages.

So there is nothing essentially functional or essentially reactive about this stuff, and so when you add Rx or "FRP" to a non-functional language, you are adding a somewhat convoluted way of expressing dataflow, convoluted because of the unnecessary detour via FP. And while it does add the ability to build reactive systems to FP languages (which otherwise lack this ability), it does not add reactivity to non-FP languages.

And although the word "reactive" and the language used to describe these systems suggest high performance, most "FRP" libraries add about an order of magnitude of overhead...so they are slow.

Compared to that, REST is straightforward and well-defined.

Meanwhile I'm going to keep writing code that does stuff, and avoid labeling it.

Purity is useful in places, but serves no purpose if complicated enough that I can't explain it to my team.

FWIW React is a nice enough library, JSX is the first and only angle bracket UI design system that I like (sorry XAML), and it all works well enough with comparatively little ramp up.

I'll let other people argue what the proper abbreviation to describe my code is.

> and avoid labeling it.

There are two hard problems in computer science: cache invalidation and naming things. Yes, and off-by-one errors.

Yes, you can just build stuff and not worry. And that can work out fine. On the other hand, muddles like these sow confusion and make sure you can't figure out how things hang together.

> 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.

Repurposing 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'.

That seems like a bug with the external system. 4xx means the request needs to be corrected to achieve success. 2xx means success, even if success means "deleted".

If a system treated 5xx responses as successful, you'd consider that a problem with the system's response handling, not a problem with your own communication of state. So why consider abuse of 4xx to be a problem with the communication protocol?

The external system didn't define the API; the service did. If you poke around on stackoverflow, you'll find quite a number of answers recommending this pattern. It's a bad idea, but it's not uncommon.
Recommending what, that a `DELETE /foo/bar` should return a 404 on success? That's flat-out wrong. It should return a 204 No Content. A subsequent `GET /foo/bar` should return a 404, but presumably the message queue isn't doing a subsequent GET but is inspecting the result of the DELETE.
Ok. But again, a bad design choice doesn’t mean using HTTP error codes is a bad idea. It means that like with anything else you need to know your tools.
If 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
So.much.experience and wisdom in this answer. I learned something new today. Thank you.
> 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.

This would reflect an incorrect design on the part of the external system.

For example:

  PUT /queue/_hyn3
  => {"name": "_hyn3"}

  GET /queue
  <= {"name": "_hyn3"}

  ... processing ...

  GET /queue/_hyn3
  404
404 is not a success condition; it's also not necessarily a permanent error.

Queues might be "reliable", but the consumers should never be assumed to be, and so it's good to have consumers provide a "complete" state update somewhere, and ideally, if the queue is able, for the queue to restore the incomplete item if the consumer fails to complete it in a specific (lengthy) period of time, because the consumer itself might have ceased to exist or failed for some other reason.

If you need to ensure that each message is consumed once and only once, you need to ensure that your queue also has something like a "completed state":

  PUT /queue/_hyn3
  => {"name": "_hyn3"}

  GET /queue
  <= {"name": "_hyn3"}

  ... processing ...

  PUT /status/_hyn3
  {"name": "_hyn3", "status": "completed"}

  GET /queue/_hyn3
  404

  GET /status/_hyn3
  {"status": "completed"}
Obviously, there's an infinite number of ways to handle the semantics here, and certainly REST is not constrained in any way to just JSON, and perhaps you would prefer to put completed in the URL, but the point is that the architecture needs to support such a use case. TL;DR: don't rely on 404 as a permanent error, but it's absolutely appropriate for a document/content/file not found, even if the content will be found later or was found earlier.
> 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.

Client certificates are very common for API authentication (well-known examples: Kubernetes, Puppet, Saltstack, service meshes like Envoy and Consul...)

Surely all these APIs do not demand client certs right? In the case of Kubernetes, a typical server cert is self-signed, so half of TLS's security measures are defeated, to mitigate that you have to white-list clients by checking their certs, but surely this is more trouble than getting a real server cert and sending your credentials in HTTP?
Server and client certificates belong to unrelated certificate hierarchies. You can have your server cert signed by $whateverCA and still run your own mini-CA to issue client certs and validate client certs against.

TLS client certificates are strictly better than passwords because they don't provide an impersonator with a wildcard (and if you are running over the internet, especially with mobile devices, then you can get into that situation w/o being subject of a targeted attack). There are fairly few ways to achieve that other than client certs (SRP and SAE come to mind, both of which have virtually no deployment).

This makes a lot more sense than the answers below thank you.
Mutual strict TLS is quite common in medium and high security environments.
the master certificate is self signed yes.

this self signed certificate now has to sign the client certificate(s). Otherwise, the clients aren't allowed to address the master.

At least thats how i've come across it. Its actually pretty common in the infrastructure world. Your OPS team can probably tell you which services utilize it in your software stack, though you as a developer probably never had to worry about it.

Though a lot of services only use a singular client certificate across all nodes and just revoke the hole chain for rotations

Sounds like these OPS teams don't know what they are doing, but I'm not sure what you are saying is correct. Conceivably, in an ideal situation, the org has an internal intermediate CA created using a cert signed by a real root CA, and that intemediate CA's cert is in every client machine the org provisions to the employees, so the employees' machine can verify the server they are connecting to is authentic. For mutual authentication, the client certs lets the servers authenticate the other way around. Using a straight up self-signed server cert is a one way mechanism from server to client, it's easily spoofed, this makes no sense to me.
its nonetheless the way its being done. a few examples:

* remote docker daemon execution

* setting up a kubernetes cluster with kubeadm and creating certificates for remote kubectl execution (this one might be related to the previous one. I'm not sure as i don't know anything about the kubernetes internals.)

* rabbitmq cluster iirc. At least thats how you're supposed to set it up with the sensu monitoring framework

* previously mentioned puppet does its as well, though the process is mostly invisible to the user

i'm not sure how its supposedly possible to spoof though?

the master needs to sign a certificate for clients. IF the master is compromised, everything is compromised. Thats true no matter which authorization protocol you're using

In properly-set-up Kubernetes, no aspect of TLS is defeated. Instead, trusted CA certs (usually self-generated) are made freely available to everyone and then those are used to validate everything. If anyone is using self-signed certs and disabling TLS validation, then their implementation is probably insecure.
s/probably/provably/, tbh
I was going to say "definitely" but then I had the idea that they could be using some kind of crazy encapsulating proxy on localhost and then still using secure transport to go across the real network... but yeah no... no one should be running k8s on real servers without (fully-validated) TLS.
Puppet uses client certs, clients request them on an initial run and an admin can approve them in an included CA. There is an API and a CLI interface.

I'm always surprised by the resistance to client certs and all the gleeful usage of pre shared keys I find. OWASP top ten bad ideas for as long as I've been writing software.

Regarding detailing errors, we have this, FWIW: https://datatracker.ietf.org/doc/rfc7807/
There's still free ranges of error codes you can use, eg. 460+ https://httpstatuses.com/
>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.

> 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.

A 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.

  I'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.

I 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)

You as an English speaker. What about the remainder of the world?

Must everything be left-to-right? What if the nouns and verbs were not English words? What if the natural order of possessives or adjectives is reversed in a romance language? What if the words are not even cognates, and the characters to express terms are not even letters, but opaque pictographs?

The paths chosen are an abstraction, and REST is designed such that it should be easy to bind any one resource to perhaps multiple URLs. But honestly, to the vast majority of the world, these URLs never see the light of day, and every consumer of a REST URL is probably going to do so programmatically, perhaps once, while reading the docs and setting up tests, and then they'll call it a day, and never look back, because honestly, consuming data from API endpoints isn't actually anyone's idea of "fun" despite wild claims to the contrary.

For the sake of getting shit done, I usually avoid this conversation in practice, but honestly, also because arguing is worthless. People have their opinions as a matter of convenience to their own efforts, and not as considerations to others.

These are the tastes of a given developer creeping in as a leaky abstraction of human readability.

If 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.

I 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.

I feel sorry for the poor guy who has to deal with your ad-hoc, informally-specified, bug-ridden, slow implementation of half of HTTP 10 years down the line.
> slow

As the author of perhaps the fastest dynamic HTTP server, I find this part particularly funny.

> informally-specified

Oh and this part. Anyone who thinks HTTP is well-specified and correctly implemented probably should be kept away from a computer.

> 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?

What about it?

That's not a problem home-users have: They NAT.

Meanwhile in the enterprise, 80/443 is frequently locked into a particular (cheap) HTTP proxy server that can't manage basic features of HTTP correctly.

> That's not a problem home-users have:

Actually, it is.

Furthermore, I'm assuming you don't expect applications to work only in the confines of a lan.

There are strong reasons why HTTP is highly favoured for communication protocols. Heck, whole industry protocols have been scrapped in favour of HTTP-based ones for this problem alone. See RTP and why it has been abandoned by HTTP-based protocols such as MPEG-DASH, and why the industry made it their point to develop a whole new video streaming protocol based on HTTP.

> Actually, it is.

I'm saying almost all home-users have NAT and can communicate to remote services on most high ports.

If you're claiming otherwise, you should be able to provide some evidence to back that up.

> There are strong reasons why HTTP is highly favoured for communication protocols.

Yes. Like where they don't control the client, as in the part right after the part you quoted.

What exactly is your point?

>I'm saying almost all home-users have NAT and can communicate to remote services on most high ports.

Sorry, that's patently false and flies in the face of reality.

>If you're claiming otherwise, you should be able to provide some evidence to back that up.

You can start here:

https://news.ycombinator.com/item?id=17569715

> Yes. Like where they don't control the client

That is patently false. The problems isn't caused by not controlling the client. The primary problem is that they don't control the network, which means each and every single node between client and server, and HTTP reduces or eliminates the chance that one of those nodes doesn't cooperate.

While 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.
For 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.

Except 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).

You 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).

Yep, 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.

> 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?

This depends on downstream caches respecting your TTLs. And, as Java has shown with their DNS implementation, that's not a reasonable expectation to hold.

You can force some of it by putting everything behind TLS, but even then there will be downstream caches for some of your customers (especially the enterprise customers with their sweet, sweet enterprise money) which will still interfere with your expected caching.

What the actual problem with caching is, is personalisation. This has nothig to do with REST.
> 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.

I 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.

I'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.