HN user

psturgeon

4 karma
Posts0
Comments13
View on HN
No posts found.

I covered all of that in a previous article and many more since. https://apisyouwonthate.com/blog/graphql-vs-rest-caching

Basically, trimming a few bits off of a request is not overall quicker than helping clients not need to make as many requests by designing an API well enough that resources can live on their own and declare their own cachability.

Designing your API resources so that primary data can be fetched and displayed before you start mucking around with secondary and tertiary data is also important. When you talk about being slower for the user, is it actually slower for a real human doing real things on the site. For example, I've seen GraphQL queries loading a social media feed, and list of friends for a little box on the side which didnt matter, and a list of comments on posts that havent even been expanded yet so now user could see it, and querying to see if there is any availability in conference rooms even if theyve not shown any interest in booking a conference room. The clients wanted to avoid making multiple calls because ooooh thats bad, but the whole page was just a blank white screen until all that pointless data came back. Querying all of those resources seperately over the same HTTP/2 connection and letting the UI progressively enhance would absolutely be quicker than mushing it all into a single giant HTTP request but that's what everyone does. All the time. It's insane.

Again, Fastly wrote about all of this very well. This article is one in a series which doesn't stand as well on its own.

https://www.fastly.com/blog/optimise-api-cache-improved-perf...

Did you read the link you shared?

19.7.1 Compatibility with HTTP/1.0 Persistent Connections

   Some clients and servers may wish to be compatible with some previous
   implementations of persistent connections in HTTP/1.0 clients and
   servers. Persistent connections in HTTP/1.0 must be explicitly
   negotiated as they are not the default behavior. HTTP/1.0
   experimental implementations of persistent connections are faulty,
   and the new facilities in HTTP/1.1 are designed to rectify these
   problems. The problem was that some existing 1.0 clients may be
   sending Keep-Alive to a proxy server that doesn't understand
   Connection, which would then erroneously forward it to the next
   inbound server, which would establish the Keep-Alive connection and
   result in a hung HTTP/1.0 proxy waiting for the close on the
   response. The result is that HTTP/1.0 clients must be prevented from
   using Keep-Alive when talking to proxies.

The whole "REST is good and everything else is dumb" is something I've tried to help people get away from for about a decade. These days it's GraphQL is good and everything else is dumb. See some of the comments in here.

I wish anything built on REST would die. Conflation of the envelope and the payload is idiotic and adds only pain, no value.

Anyway, a reasoned conversation about where REST can be useful even today: https://apisyouwonthate.com/blog/rest-and-hypermedia-in-2019

And a technical comparison for when people need it: https://apisyouwonthate.com/blog/understanding-rpc-rest-and-...

And when those technical differences can come in useful or just be annoying: https://apisyouwonthate.com/blog/picking-the-right-api-parad...

Loooooots of content on all this. :)

If you make your quotes small enough you can make them mean anything, but I invite you to go take a look at the dissertation. "large-grained resources" does not mean "compound documents", the REST dissertation has no comment on compound documents or anything that resembles the concept, which came along later. It doesn't forbid them or allow them, but many of the concepts of REST suggest otherwise.

Beyond whether its RESTful API or not (grey area) it adds headaches, and is rather unnecessary with good API design anyway, which is what this article was about.

More importantly, compound documents mess with the "cacheability" of resources. A resource cannot declare its own cacheability (which REST suggests) through the uniform interface when its munged into a mismatch of other data. A foo and a bar and a baz are now all cached in together under the same headers with the same /foo?include=bar,baz identifer, meaning that if a bar is likely to change often you have to request the whole thing again. This is one of many reasons compound documents are a pain in the ass, but there are plenty more.

Fastly wrote about all this: https://www.fastly.com/blog/optimise-api-cache-improved-perf...

The current praise of HTTP/2 as a major win for REST APIs shows how differently "REST" is understood by its proponents today compared to its original meaning. If doing REST today is about doing the opposite of what it was intended to do, it also raises the question why do we believe we get the same benefits REST did for its original definition? A quick read shows we don't, but the cultural ingraining in favor of "believing" is huge.

This whole paragraph makes no sense. I have been making APIs since ~2008 so let's not act like I'm brand new at this.

The point I was making here is that in the past people have moaned about REST because "making lots of requests is slow", which is a common comment from people who generally build their APIs poorly not taking into consideration what the consumers would be doing and just flopped out a very normalized database and forced clients to construct their own data models from that. It's also a concern from people who havent got the first clue what HATEOAS means or how it can help abstract state from multiple clients up into the backend. They just see it as "having to make more requests".

Now that the fear of multiple requests is subsiding, the exact same concepts that made REST beneficial for many APIs in the HTTP/1.x past exist now, they're just quicker in HTTP/2. And they're quicker in HTTP/3. REST and HTTP just get quicker and more useful over time.

Anyway, you sound like you might enjoy this article: https://apisyouwonthate.com/blog/rest-and-hypermedia-in-2019

Ignoring all the layers of HTTP to use it as a dumb tunnel is a really effective way of forcing everyone to reinvent a lot of wheels at every phase of the interaction. A lot of people do it, its usually a brittle and expensive waste of time.

There's loads of problems and I've been talking about them all through a series of blog posts and talks, I just didn't cover it here.

The main problem is that tertiary data slows down primary data.

Put simply, when you request 3 things, it might take a little while for the server to find process the response, create all the JSON, shove it all over the wire, and be picked up by your client application.

The user has been sat there waiting for all three things to come back at once.

Real world example: a social network full of posts and images is failing to load because the application wanted to know if there was any space left in a meeting room nearby.

If you have 3 different things they probably have different cacheability, so let them declare their own cacheability and let the client only bother fetching them if they need to. Show the things you have when you get them. Progressively enhance the page. Don't just show nothing.

There's a lot of solutions to various problems with compound document systems like JSON:API and I've written about those too: https://apisyouwonthate.com/blog/making-the-most-of-jsonapi

But the core purpose of compound documents was the same thinking as CSS combination and Image Sprites, most of which have gone away now, and I think compound documents should too. They were a handy hack that had downsides and its no longer necessary to mess with them.

As a consultant I meet a lot of people who think the goals of REST are pointless and have created an absolute shitshow of poor API design, reinventing loads of wheels and getting to a point they had to get me to come in. Usually explaining the background for why those goals are not pointless is the first step to unfucking their API ecosystem.

https://apisyouwonthate.com/blog/rest-and-hypermedia-in-2019

That's a post which aims to explain the tangible benefits of each step, but I've got plenty more articles explaining when REST is overkill and simple RPC would be a better fit.

Hi, I am not assuming all microservices are in the same data center.

Your reply assumes that API requests need to be made in sequence. If you need 3 resources, and you make 3 requests, you are not waiting for 1 then 2 then 3. 1 and 2 and 3 are all coming back along the multiplexed connection and none are blocking the other. That is generally what a lot of compound documents are doing, but sure the article also talks about when you need to know some information from 1 before you can call 2 or 3.

- Server Push - since axed from some browsers, but the idea there is to proactively push the resource to you before you request it, because you know people often request Bar after requesting Foo. That means its not 1s it could be 100ms or less. The GraphQL community took this idea and created @defer.

- If people ALWAYS need to request 1 and 2 and 3, that API sounds like it was overly normalized and not too well planned. Maybe its more of a "Data Store" than an API.

It also talks about how by making endpoints smaller and more targeted, the cachability of one resource does not impact another, so you dont need to wait 1s for each requests, you just skip a lot of the requests. This article covers a lot of the same points.

https://www.fastly.com/blog/optimise-api-cache-improved-perf...

It sounds nice at first, but if you have 5 completely different resources then why would you want to squish them into one? This taints highly cacheable data with frequently changing data, and slows down everything all at the same time.

Also when 5 becomes 8, 9, 10.... entire APIs come grinding to a halt because people are trying to download the entire database in one single request instead of just making a few calls.