Another con of GraphQL (and probably GRPC) is caching. You basically get it for free with REST.
REST can also return protobufs, with content type application/x-protobuf. Heck, it can return any Content-Type. It doesn't have to be confined to JSON.
GRPC needs to support the language you're using. It does support a lot of the popular languages now. But most languages have some sort of http server or client to handle REST.
I think the benefits of HTTP caching are often exaggerated, especially for APIs and single page applications.
Often I’ll want much more control over caching and cache invalidation than what you can do with HTTP caching.
I’d be interested to see an analysis of major websites usage of HTTP caching on non-static (i.e. not images, JS, etc) resources. I bet it’s pretty minimal.
GraphQl queries are often send over an HTTP endpoint. This allows you to take advantage of caching where necessary (but then enough apps don't cache HTTP either).
For example you want to make sure large resource blobs (e.g. pictures are cached).
In this case you can decide to not put them in the GraphQl response but instead put a REST uri of them there and then have a endpoint like `/blobs/<some-kind-of-uid>` or `/blobs/pictures/<id>` or similar.
The same endpoints also can be used for pushing new resources (GraphQl creates a "empty" `/blobs/<id>` entry to which you than can push).
While this entails an additional round-trip and is properly not the best usage for some cases for others like e.g. (not small) file up-/down-load it is quite nice as this is a operation often explicitly triggered by a user in a way where the additional roundtrip time doesn't matter at all. An additional benefit is that it can make thinks like halting and resuming downloads and similar easier.
Cacheability isn't just about the transfer, it's also about decreasing server load in a lot of applications. An expensive query might return a few bytes of JSON, but may be something you want to avoid hitting repeatedly.
I believe that GraphQL handles this with "persisted queries." Basically, you ask the server to "run standard query 'queryname'." Since it is a standard, predefined query you can cache the results.
Well actually, it can actually be more advanced with GraphQL. In fact GQL clients have the ability to invalidate caches if it knows the same ID has been deleted or edited and can in some cases even avoid a new fetch.
That being said some of those advanced use cases may be off by default in Apollo.
REST can also return protobufs, with content type application/x-protobuf. Heck, it can return any Content-Type. It doesn't have to be confined to JSON.
GRPC needs to support the language you're using. It does support a lot of the popular languages now. But most languages have some sort of http server or client to handle REST.