With an API that keeps tighter control over access patterns, you've got a more predictable target for optimizing your indexing strategy. With GraphQL, you've got to worry about the possibility that some client figures out how to craft a query that slips between all your indexes and causes the database engine to resort to doing things the hard way. So, worrying about that stuff is hard, where it tends to be easier to manage with REST or gRPC because you can just force your worldview onto consumers and get on with your life.
In theory, though, a well-crafted GraphQL API can be more performant over a wider variety of use cases than a well-crafted REST API, for all the oft-cited reasons. So it does make the impossible possible. But not (necessarily) easy.
How do you do that? https://github.com/graphql/dataloader
However, to be super efficient you need to give up on some consistency. You simply can't have data points which join directly in the db. Instead, you need to make separate parallel requests for those datapoints and let the dataloader be in charge of merging them into larger batches of requests for the db to fullfill.
This can result in some additional latency on a request, but ultimately provides the best way to be able to scale things out.
The benefit of rest is that it's easier to make a really fast on single request endpoint. You can precisely tune your db indexes to match your queries. For graphql to be fast and not kill your DB with a malicious query, you need to introduce that wait time/batching.
I fear, sometimes, that our collective tendency to prefer talking about the most interesting or most capable technologies tends to bias us toward over-engineering. Slinging JSON over HTTP is, in my personal opinion, a pretty hokey hack. But it's also the option that's the easiest to implement, the most widely understood, and, more often than not, it's more than up to the task.
I promise you, this is not the best way to scale things out.
There may be other ways to scale things out, but that doesn’t mean this one isn’t good.
F.e. when we knew that we are going to have a big spike because of a feature in the news, we checked the cost of our queries and heavily optimized and added a cache just for those queries that are costing us the most in front of our backend (based on the query string). This enabled us scaling up from 2000 concurrent users to half a million (the difference is only that big because we were super badly unoptimized before and also the near infinite limit of Cloudflare workers)
It's definitely harder when you have bigger different teams interacting with a single central GraphQL api. My rule for that is that there needs to be a gateway that handles exactly that for every service/team/whatever. Not custom coded by every team because this 100% gets mismanaged. Instead it should be just a container image managed by the same team that handles the GraphQL api and configured by the consuming team via an env var or a file containing all the queries needed.
If so, I do agree with that statement.
Perhaps that's my bias showing. Lately I've mostly been working in Java, a context where the words "easy" and "Web" rarely belong together in the same sentence.
I like that one! Yeah, I totally thought it was a typo, but I do think that GraphQL makes very complicated things easy. I might also be biased because I've been working with it for a while now.
So its relative merits have a lot to do with how complicated a thing you're trying to do in the first place.