Why We aren't using `GraphQL`? π
nelsonic opened this issue Β· 5 comments
As you can see from the last-updated date on this repo, π§βπ»
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 ... π
Our Experience
We've used GraphQL
in 3 contexts:
Serverless
-AWS Lambda
functions were used to resolve data fromDynamoDB
. These added a minimum of200ms
latency to each query sent from the frontend and in some cases the resolver would take800ms
. This is an unacceptable delay that made every interaction on the Mobile App even on a1Gbps
connection feel Sloooooowww π- 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 runningGraphQL
"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!!
- Integrated - a recent client project used
Absinthe
inElixir
https://github.com/absinthe-graphql/absinthe it was faster than theApollo
Server but instead of defining data in 2 places, now it's 3!! EachGraphQL
endpoint requires it's ownSchema
which then resolves to function that retrieves data fromEcto
... i.e. Maintenance Nightmare! π’
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 π΄οΈ
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.
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.
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
https://blog.twitter.com/engineering/en_us/topics/infrastructure/2020/rebuild_twitter_public_api_2020
Seriously, read through this Engineering Blog post.
Search for instances of engineering-focussed keywords such as "performance" or "latency":
"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
https://developer.twitter.com/en/search-results?q=graphql
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:
- https://blog.logrocket.com/graphql-vs-rest-api-why-you-shouldnt-use-graphql
- https://dev.to/andyrewlee/why-i-no-longer-use-graphql-for-new-projects-1oig
Why I Donβt Use GraphQL Anymore: https://youtu.be/S1wQ0WvJK64?t=187
"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.
This issue feels like it needs to be in the readme!
@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. π
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.
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
https://www.softwareatscale.dev/p/the-hidden-performance-cost-of-nodejs
The Hidden Cost Of GraphQL And NodeJS: https://youtu.be/i0YfiQlzv6M