However, that is missing the point. What we need to talk about first is, how you want to invalidate your cache. Do you want to set a TTL of 60 seconds? That might work for certain apps - both in REST and GraphQL, but many apps can't afford stale content for such an amount of time.
You'll need cache invalidation when content changes. That on its own is a hard problem, no matter if REST, GraphQL or any other protocol. And it is one of the main reasons we built GraphCDN: Making it easy to purge the cache, when relevant content changed. How? We give you a purging api (also GraphQL) and additionally GraphQL has the concepts of mutations. Once you run a mutation through GraphCDN, it'll detect the relevant entities involved and purge the cache accordingly.
So - yes, in GraphQL caching on the surface might seem harder - but we're not just solving the "I can't cache POST requests" problem, but rather give you powerful cache purging - which is only possible due to the well-defined structure of a typed GraphQL Schema.
Because of that, we're actually thinking of providing REST "connectors" one day - turning REST into GraphQL, so you can have one unified interface that is easy to cache and invalidate.
Or you can use Vercel's stale-while-revalidate which will update the cache periodically while (temporarily) serving stale responses.
Most of our customers even use both things together to reduce the likelyhood for stale content.
This has a couple of limitations that you'd also expect from a CDN cache for REST requests. However, I believe the interesting part about GraphCDN is that it can do more to look at the exact queries and mutations that are run to invalidate queries more precisely.
So, it's likely worth saying that it's not that CDN caching GraphQL is hard, but getting invalidation and a high cache hit rate (just as with REST APIs) is hard.
The frontend teams may not want direct access to a backend teams database. But they do want the backend to be flexible, and graphql allows for that.
I don't think a normal HTTP api provides anything to help with cache invalidation after a write operation, does it?
Etags can be used to check and invalidate content.
It solves some problems on the querying side (that not everyone has). OTOH implementing it server-side is a major pain unless you rely on third party stuff like Hasura or GraphCDN.
Personally I'll keep using REST as the default for the foreseeable future, and only use GraphQL when the problems it solves are more painful than the problems it introduces.
I'm not even sure "major pain" suffices to describe it. It's such a mine-field to implement that if it's tractable and non-insane to do so for one's project, then the surface area of one's API must have been so tiny that using GraphQL was entirely unwarranted in the first place.
[EDIT] I take that back: it can be fairly easy if your dataset is 100% public, read-only, and you don't care whatsoever about performance or limiting abuse.