dwyl / learn-graphQL

❓Learn to use GraphQL - A query language that allows client applications to specify their data fetching requirements
45 stars 4 forks source link

Why We aren't using `GraphQL`? 🐌 #23

Closed nelsonic closed 3 months ago

nelsonic commented 1 year ago

As you can see from the last-updated date on this repo, πŸ§‘β€πŸ’»

image

we haven't expanded our knowledge of GraphQL in a few years. βŒ› We have experience of using GraphQL in production in several places. 🏦 It's universally slower than the equivalent REST API or Socket stream ... 🐌

On the surface it seems like a good idea to model your desired response data in the query. πŸ’­ You can traverse a graph of data and return the related results. 😍 What's not to like? πŸ€·β€β™‚οΈ

GraphQL Makes Your App Sloooooooooooooowww ... 🐌

fork-in-road-graphql-embedded

Our Experience

We've used GraphQL in 3 contexts:

  1. Serverless - AWS Lambda functions were used to resolve data from DynamoDB. These added a minimum of 200ms latency to each query sent from the frontend and in some cases the resolver would take 800ms. This is an unacceptable delay that made every interaction on the Mobile App even on a 1Gbps connection feel Sloooooowww 🐌
  2. As-a-service - an Apollo Server was run on an EC2 instance and served all the GraphQL queries, which then had to be resolved to several other services e.g. 3rd Party APIs. This was a marginal improvement over running GraphQL "serverless" but still created duplication of effort because every 3rd Party API required it's own "resolver". There was so much code in the repo and it ended up being so slow it was embarrassing to watch people using the App in demos ... ⏳ πŸ€¦β€β™‚οΈ

    Note: I wrote one of the resolvers and mostly copy-pasted code from another place. That was the norm. Copy-pasted code everywhere!! When I suggested making a library the "Director of Engineering" said "no". Horrible maintenance nightmare!!

  3. Integrated - a recent client project used Absinthe in Elixir https://github.com/absinthe-graphql/absinthe it was faster than the Apollo Server but instead of defining data in 2 places, now it's 3!! Each GraphQL endpoint requires it's own Schema which then resolves to function that retrieves data from Ecto ... i.e. Maintenance Nightmare! 😒
image

Whenever you read the word "modern" think "more complex" or "worse". Adding a layer of GraphQL on top of your existing database means you have to resolve the queries. This means you have to write all code twice and maintain those queries. When something changes, you have to change and test it in both places. This automatically increases [in many cases doubles] costs. And what for? Does it offer a speed boost to the people using the App you're building? Heck no!! It makes your App slower. In every case.

So why do people keep doing it? πŸ€·β€β™‚οΈ One word:

Fashion πŸ•΄οΈ

image /fashion-fails

Fashion doesn't have to be practical. It's all about being noticed. People who are bored and generally don't have much substance to them feel the need to peacock for attention ... It's no different in the tech world. Why build a "boring" low-latency API that means people using your App can get their job done faster when you can build a slow API with a "Graph" interface that is substantially slower? Answer: to impress your peers with cool-sounding names. πŸ™„

Chose the "boring" but fast solution every time. Leave the complexity to your competitors. If someone on your team is tempted to use GraphQL tell them to create a sample project with non-trivial data and compare the query resolution of the GraphQL API vs. using "raw" Websockets.

There may be a use-case where GraphQL is "better", e.g. where you would need to perform multiple REST API queries to retrieve the same data.

Dynamic Data / Response

A use-case that could make sense: We originally explored using GraphQL when we were re-building Search at a travel company where there were multiple parameters such as number of passengers, ages, meal preferences, etc. There wasn't one single API endpoint that could return all the data at once. So we used GraphQL to dynamically build the query in the front-end, assemble all the required bits in the back-end and then the result would have the same "shape" as the query so it would be easier to display. That was the theory at least. The reality was that we were just shifting query complexity from one place to another. The resolvers in the GraphQL server still had to "assemble" all the data to service the query. The GraphQL server made as many as 30 HTTP requests to return the needed data from various internal microservices. ⏳ And if you know anything about asynchronous request processing and the theory of constraints, this meant that the response returned by the GraphQL server was subjected to the slowest returning HTTP request. i.e. if one request took 1300ms to return, it didn't matter if the others were 200-400ms the response was always slow.

This is a horrible way to build an API!! πŸ˜•

Instead, the way that respects the person/people using the App is to respond as quickly as possible with the most relevant data and then gradually return more data as it become available.

image

You don't need Yeezys to go for a walk outside, you need affordable comfortable & functional shoes. You don't need GraphQL to build an API/App. You need something fast that isn't fashionable.

If you're building something "kΓΌle" to impress someone, do it as a side-project in your own time. But please run some benchmarks on it so you know how slow and pointless it is!! πŸ™ Build your API around the queries people make most often and optimise for the speed not fashion.

nelsonic commented 1 year ago

I hereby invite anyone using GraphQL in Production to share metrics of response times being faster using GraphQL instead of "boring" REST API. πŸ™

If you care about the people using your App and don't want to waste their time on every request/response. You won't be using GraphQL; at least not as the core API.

A couple of years ago, Twitter made a splash talking about their "V2 API":

https://about.sourcegraph.com/blog/graphql/graphql-at-twitter

graphql-at-twitter-no-performance

https://blog.twitter.com/engineering/en_us/topics/infrastructure/2020/rebuild_twitter_public_api_2020

image

Seriously, read through this Engineering Blog post. Search for instances of engineering-focussed keywords such as "performance" or "latency":

twitter-api-latency twitter-latency-perf

"Latency is a time delay between the cause and the effect of some physical change in the system being observed." ~ https://en.wikipedia.org/wiki/Latency_(engineering)

What was Wrong With the "Old" API?

The "old" API was perfectly fine. We used it: e.g: dwyl/meteor-search There was a real-time socket based API and everything was perfectly stable. But there was a shiny new toy and Twitter Devs couldn't help themselves. They re-built backend as microservices and API using GraphQL ... Billions burned on a bonfire. No improvement to the API. No leap in usage. πŸ’Έ πŸ”₯

Meanwhile ...

Meanwhile, days after Elon acquired the LOSS Making platform, they magically reduced core service Latency by 400ms: https://twitter.com/elonmusk/status/1597829226572705793

image

https://developer.twitter.com/en/search-results?q=graphql

twitter-graphql-no-results

Coincidence?

The whole team of people that worked on GraphQL at Twitter left: https://twitter.com/hashtag/LoveWhereYouWorked see: linkedin.com/feed/update/urn:li:activity:7004090039634644993

Very curious why ... πŸ’­ Obviously the superficial reason is that Elon is a douche and nobody wants to work for/with him. πŸ€¦β€β™‚οΈ But what is the real reason? πŸ€·β€β™‚οΈ Could it be that Twitter just doesn't need GraphQL to provide it's services and APIs? πŸ€”

Sadly, you won't read about the complexity on any of the promotional materials on https://www.graphql.com ...

Recommend reading:

Why I Don’t Use GraphQL Anymore: https://youtu.be/S1wQ0WvJK64?t=187

image

"deep well of complexity" ...

if your objective is job security, then definitely implement GraphQL everywhere! But if you want to keep something simple and performant, give it a hard pass.

iteles commented 1 year ago

This issue feels like it needs to be in the readme!

nelsonic commented 1 year ago

@iteles we could put it in the README.md but I just wanted to capture some thoughts so that I could share. πŸ”— Ultimately, I'm not going to change the minds of the Devs who have been brainwashed by Facebook's Marketing Machine. πŸ˜•

nelsonic commented 1 year ago

Sadly, Facebook is not in the business of minimising response times in their services. In fact, quite the opposite is true they measure and optimise for time-on-site:

Facebook's objective is to:
"consume as much of your time
and conscious attention as possible."
~ Sean Parker, Former Facebook President

Therefore they don't care if each/every request takes 100-400ms longer. They want the service to be just "fast enough" so people don't quit the App, but those extra ms per page load add up to more time spent on the site. They have a perverse incentive to not make their service as fast as possible!! And what's more, because they are systematically slowing down their own service, they have a huge vested interest in proliferating the technology.

The more companies use GraphQL to make their APIs/Apps/Services substantially slower, the more Facebook & Co. with their deliberately slow API will appear to be "normal". It's not "normal" to waste people's time, but that's Facebook's entire business model.

nelsonic commented 1 month ago

https://bessey.dev/blog/2024/05/24/why-im-over-graphql/ I Am Done With Graph QL After 6 Years: https://youtu.be/XBUsRVepF-8

image

https://www.softwareatscale.dev/p/the-hidden-performance-cost-of-nodejs The Hidden Cost Of GraphQL And NodeJS: https://youtu.be/i0YfiQlzv6M

image