DEV Community

Cover image for What are the cons of GraphQL?
Kumar Abhirup
Kumar Abhirup

Posted on

What are the cons of GraphQL?

I bet everyone here has heard about, used and loved GraphQL over REST API. I also know the reasons why GraphQL is better than REST API.

BUT

Everything comes with drawbacks.

Even today, not all new startups and apps use GraphQL in their backend.


What could be the reason?

What is the biggest hurdle you face when you learn/work with GraphQL?

And what are the solutions to it?

What are the CONS of GraphQL?


I am asking just for the sake of knowing why some people might not like GraphQL.

I ❤️ GraphQL.

#devDiscuss

Top comments (42)

Collapse
 
rhymes profile image
rhymes

I think the biggest con of GraphQL is the loss of network caching. You can't use thousand year old HTTP caching and various proxies but it might not be a problem, depending on the case. This is a great explanation phil.tech/api/2017/01/26/graphql-v...

Collapse
 
benbot profile image
Benjamin Botwin • Edited

I don't know if I agree with this. You can have a similar cache setup as you do with a REST api as long as you, say, hash the graphql query or something and just hit the cash server side if the graphql query hashes match.

Most clients aren't sending a variable number of different graphql queries anyway. Most have a fixed set of queries that get sent from different pages.

It may not be as straightforward as REST caching, but it's not very complicated either.

Collapse
 
rhymes profile image
rhymes • Edited

I think we're talking about two different types of cache. You can definitely do server side caching with either. After all if you're on the server you own the data so you can cache it however you want.

I meant network servers, as the HTTP spec says that GETs are idempotent, network servers (proxies, cdns, edge caching services) cache data, that can't easily happen with GraphQL by default, because all queries (even read queries) are transmitted using POST:

Due to the way GraphQL operates as a query language POSTing against a single endpoint, HTTP is demoted to the role of a dumb tunnel, making network caching tools like Varnish, Squid, Fastly, etc. entirely useless.

(taken from phil.tech/api/2017/01/26/graphql-v...)

It's not the end of the world, but it might mean that you have to get creative with your data for the fact you're suddenly losing the advantage of proxies.

There are standards popping up but on one side you have a decade year old system that works (and it's widely used by clients, networks and servers) for caching and on the other side you have to control both the client and the server if you want to have caching done right.

As the author was asking about the cons, and this I think is a con :)

Thread Thread
 
benbot profile image
Benjamin Botwin

Ah okay, I see what you’re saying. I was getting the network layer and application layer mixed up.

Though, while that’s true for now, I don’t see why tools like varnish couldn’t be extended to cache GraphQL responses at the network layer. If the adoption of GraphQL keeps increasing, we’ll eventually see solutions.

Thread Thread
 
mando75 profile image
Bryan Müller

Just to add a bit to the discussion, I would encourage anyone interested in this thread to listen to this talk from GraphQL Summit on HTTP and caching in general with GraphQL. It was given by a senior platform engineer at GitHub. He goes pretty in depth comparing caching in GraphQL vs in a traditional REST API (Including HTTP caching). I think he does a good job of explaining the pros and cons with both patterns. youtube.com/watch?v=CV3puKM_G14

Thread Thread
 
rhymes profile image
rhymes

Thanks Bryan, very interesting!

Collapse
 
kumareth profile image
Kumar Abhirup

thanks for the info

Collapse
 
leighshammer profile image
Leigh Barnes

I k ow from within react builds using Apollo as the connector the individual caching is pretty solid and I haven't seen much in terms of drawbacks. Where I am wanting to cache the actual responses to serve to multiple individual connections i didn't find abstracting the backend calls with my own cache layer and serving / invalidating with a redis layer any more complex than I have with rest api's over the years.

Collapse
 
florianrappl profile image
Florian Rappl

Besides the mentioned drawbacks one that I see is that instead of relying purely on JSON they invented a custom DSL (wrapped inside a JSON), which comes with a custom parser that adds a substantial amount of JS to your code. In our case we we went from a ~380k bundle to a 600k bundle (before gzip).

Collapse
 
benbot profile image
Benjamin Botwin

Why do you have a graphql parser on your frontend?

Collapse
 
florianrappl profile image
Florian Rappl

Practically all clients (e.g., Apollo, urql) come with a query evaluation which requires a parser. This is not the schema parser, but it's still part of the graphql standard lib.

So if your client relies on the graphql package you have a parser in there, too.

Thread Thread
 
benbot profile image
Benjamin Botwin

I just took a look and neither urql, Apollo-client, react-Apollo, nor their dependencies have the graphql package as a dependency.

Unless I just missed it, you shouldn’t have a graphql parser client side

Thread Thread
 
florianrappl profile image
Florian Rappl

Sorry either you don't know these libs or you just like trash talk.

  1. Apollo ships with it's own implementation. It still parses the queries (it needs to for several reasons).
  2. urql has a peer dep to graphql. See github.com/FormidableLabs/urql/blo....

Still a parser is needed as all these libs perform validation up front and provide additional capabilities such as caching. They could all be added without additional parsing, but then it would be more cumbersome for the dev thus making the abstraction useless.

Thread Thread
 
benbot profile image
Benjamin Botwin

Jeezus man chill out. I just checked their deps on npmjs.org.

Didn’t know to check peer deps.
Nor did I know that apollo shipped their own.

Thread Thread
 
gklijs profile image
Gerard Klijs

You can do without. The Clojurescript client just sends a string over the wire, and get a Clojure map back.

Thread Thread
 
benbot profile image
Benjamin Botwin

That’s what I was thinking, but, I guess, Apollo needs some info on the query for it’s caching solution.

Thread Thread
 
gklijs profile image
Gerard Klijs

That makes sense. The Clojurescript library is more low level. It might be nice to have something similar to Apollo. But I quite like the simplicity of just binding the results of a query to some data in de dB. It's also easy to combine queries and subscriptions that way.

Thread Thread
 
benbot profile image
Benjamin Botwin

The big draw to Apollo for me is honestly not so much the caching, alththats a big plus, but the fact that GraphQL-codegen can make fully typed Apollo hooks for each GraphQL query or mutation I write.

It’s magical.

Thread Thread
 
gklijs profile image
Gerard Klijs

Clojurescript isn't typed so that won't work :P. Although you could build something similar using spec. You could even use generative testing out of the box that way for components created that way.

Collapse
 
kumareth profile image
Kumar Abhirup

OMG, that 600k is huge.

Collapse
 
mando75 profile image
Bryan Müller

I've worked with GraphQL quite a bit in both personal and professional settings. In my experience working with several teams in both new and existing GraphQL APIs, the biggest challenge has been schema design and management.

Maintaining a large schema can be really hard, especially when working across multiple teams with varying levels of experience with GraphQL. With REST, each endpoint is mostly isolated, which makes it easy to either make changes to or move endpoints to a new api version. In GraphQL, the schema is supposed to stay version-less by evolving over time. This means you need to think carefully about what you include in your GraphQL types, and how you structure your type relationships. If you create complex relationships that your clients begin to rely on, it can really hurt you later on.

The advice typically is to make small incremental changes to your schema as needed, but for many teams inexperienced with GraphQL, they don't take the time to focus on really understanding how their data graph should be structured.

Not to say that it isn't easy to mess up the design of a REST API, but I think in a lot of cases it is harder to fix a poorly designed GraphQL API due to the lack of versioning.

Collapse
 
gklijs profile image
Gerard Klijs

Yes, where with REST you risk having small differences between different endpoints causing errors. We work api first with REST, but there are at least 3 ways of doing pagination, and that's with about 50 developers.

Collapse
 
mando75 profile image
Bryan Müller

Absolutely true, although I would mention that if you are running a Federated schema for multiple services managed by multiple teams, you can do the same thing in GraphQL unless you enforce a strict pagination standard like Relay.

BTW, just wanted to say thanks for your great talk on using Kafka to back subscriptions at Summit. We've been looking into doing something similar to back our first subscription service so it was great to hear some of your insights :).

Collapse
 
kumareth profile image
Kumar Abhirup

Interesting take. Makes complete sense.

Collapse
 
dorshinar profile image
Dor Shinar

Queries can be more expensive to run - due to the multiple layers of resolvers and schema validation, nested queries can be more expensive. Schema validation is a big plus, don't get me wrong, but it does come with a trade-off.

Collapse
 
kumareth profile image
Kumar Abhirup

thanks for the info

Collapse
 
gklijs profile image
Gerard Klijs

Queries might be more expensive, but using data loader one GraphQL query could be one query to the database, which with REST it might needed hundred simpler calls.

Collapse
 
totally_waqas profile image
Waqas

it’s just beautiful how data loaders work

Collapse
 
benbot profile image
Benjamin Botwin

GraphQL isn’t a framework though it’s a protocol. It’s another protocol layer on top of HTTP, sure, but it doesn’t force you into any way of building an app like a framework does.

What makes you think it’s a leaky abstraction? It seems like REST is a much leakier abstraction over any dataset since it’s much more work to modify a rest api and clients than it is to correct a single graphql resolver.

Collapse
 
leighshammer profile image
Leigh Barnes • Edited

I would say as you mentioned just the knowledge and learning, which is no worse than any new tooling.

Of that the one draw back I have is within the query syntax itself on consumption and getting to grips with the query/mutation fragmentation syntax a bit of a steep learning curve but easily surmounted. :)

Where rest does win is often with simple get calls for micro data where mapping the fields will take double the time to schematics forward. In these cases I have abstracted the calls into a simple get endpoint alongside my app build to save the bloat on the frontend.

Very little other than that I can think of as far as cons.

Collapse
 
alediaferia profile image
Alessandro Diaferia

Another thing to keep in mind in addition to everything that's been mentioned already is that instrumentation requires a little additional effort. You normally get response time metrics almost for free with the majority of frameworks but you're hardly gonna get resolver-level granularity instrumentation with GraphQL unless you build it yourself.

Collapse
 
jtwebman profile image
JT Turner

I love it as well. A few down sides is consumers have learn a new way of requesting data. Over selection is something you have to handle. Error handling is strange and everyone does it different. I think the advantages out way these issue but not everyone agrees.

Collapse
 
gklijs profile image
Gerard Klijs

One thing that hasn't been called yet is the the spec itself or pretty open. In practice it's not a big problem, because most clients and servers take inspiration from how Appolo did it. For example some servers and some clients allow to do queries and mutations over a websocket, but some don't.

 
benbot profile image
Benjamin Botwin

Your client needs knowledge and implementation with REST as well since the structure of data is static and defined server side.

And if you change a rest endpoint, you’d likewise have to change all clients, since they have no say in the response’s structure.

The abstraction Grapqhl provides allows you to make api changes server side without affecting the data structure the clients expect.

And yeah there’s no heat here, sorry if it came off like that 😅

Hammering out these small differences can provide some good insights is all.

Thread Thread
 
sample profile image
Ian

"And if you change a rest endpoint, you’d likewise have to change all clients, since they have no say in the response’s structure." What? No, you change the version.

Collapse
 
dorshinar profile image
Dor Shinar • Edited

I partially agree with most of what you said, but please explain how you have less static types in your code? Schema validation comes built in, and works both ways (you can't receive an invalid parameter nor can you send)

Collapse
 
spock123 profile image
Lars Rye Jeppesen

Caching

Collapse
 
kumareth profile image
Kumar Abhirup

🙌

Collapse
 
lukaszwiktor profile image
Łukasz Wiktor

Inability to fetch all fields with a wildcard:
github.com/graphql/graphql-spec/is...

Collapse
 
kumareth profile image
Kumar Abhirup

🔥