Esteban Herrera Family man. Java and JavaScript developer. Swift and VR/AR hobbyist. Like books, movies, and still trying many things. Find me at eherrera.net

Why you shouldn’t use GraphQL

6 min read 1892

Why You Shouldn't Use GraphQL

Editor’s note: This post was last updated on 3 May 2021.

Is GraphQL bad? Certainly not; GraphQL is great if you want to work in a declarative style because it enables you to select only the information or operations you need. However, depending on your use case, performance requirements, and tolerance for unnecessary complexity, GraphQL could be a bad fit for your project.

In this guide, we’ll go over some reasons why you should consider using a REST architecture instead of GraphQL. We’ll discuss some drawbacks to using GraphQL, including performance issues and problems with GraphQL schemas and complex queries. We’ll also outline some common GraphQL use cases and tips to help you determine when to use GraphQL vs. REST.

Here’s what we’ll cover:

What’s the difference between GraphQL and REST?

The major difference between GraphQL and REST is the manner in which data is sent to the client. Whereas, in a REST architecture, the client makes an HTTP request and data is sent as HTTP response, in GraphQL, the client request data with queries.

It’s also worth noting that, in REST, the structure of the request object is defined on the server. In GraphL, you define the object on the client.

Why and when to use GraphQL

The objective of this guide is to explain some reasons why GraphQL might be a bad fit for your project, but it wouldn’t be fair to proceed without highlighting the benefits of using GraphQL.

GraphQL is an excellent solution to a unique problem around building and consuming APIs. When used as designed, it can be an ideal tool for the use cases described below.

Data fetching control

GraphQL was designed to allow the client to ask for only the data it needs. While the server might be able to deliver more data to the client for a single request, it would only send the data requested by the client. If you want the client to control the type and amount of data it needs, GraphQL would be ideal for your project.

Using multiple data sources

GraphQL simplifies the task of aggregating data from multiple sources or APIs and then resolving the data to the client in a single API call. Other API technologies such as REST would require multiple HTTP calls to access data from multiple sources.

We made a custom demo for .
No really. Click here to check it out.

Alleviating bandwidth concerns

Bandwidth is a problem for small devices such as mobile phones, smartwatches, and IoT devices that are not able to handle large amounts of data. Using GraphQL helps minimize this issue.

Rapid prototyping

GraphQL exposes a single endpoint that allows you to access multiple resources. Also, resources are not exposed according to the views that you have inside your app. So if your UI changes — i.e., requires either more or less data — it doesn’t have an impact or require changes on the server.

Why GraphQL could be a bad fit

Now that we’ve outlined some use cases that call for using GraphQL, let’s get to the heart of the matter and discuss some reasons why you might want to consider using REST instead.

Below are some reasons why GraphQL could be a bad fit for your project when compared to a REST architecture:

  1. GraphQL queries could cause performance issues
  2. REST can do much of what GraphQL does
  3. GraphQL makes some tasks more complex
  4. It’s easier to use a web cache with REST than with GraphQL
  5. The way GraphQL schemas work could be a problem
  6. REST is better for error handling and tooling

Let’s examine each case in more detail and review some tips to help you determine when to use GraphQL and when to use a REST architecture.

1. GraphQL performance issues

As mentioned above, GraphQL, being a query language for APIs, gives clients the power to execute queries to get exactly what they need. But what if a client sends a query asking for a lot of fields and resources? For example, “Give me the information about the users that posted a review for all the books of this author”:

author(id: '1234') {
  id
  name
  books {
    id
    title
    reviews {
      text
      date
      user {
        id
        name
      }
    }
  }
}

You can simply let your users run any query they want. A GraphQL API must be carefully designed; it’s not just about putting it on top of a REST API or a database.

For complex queries, a REST API might be easier to design because you can establish multiple endpoints for specific needs, and for each, you can fine-tune specific queries to retrieve the data in an efficient way.

This might be a bit controversial because multiple network calls can also take a lot of time. But if you’re not careful, a few big queries can bring your server down to its knees. In that sense, GraphQL’s greatest strength can also be its greatest weakness.

In a GraphQL API, tools such as Dataloader allow you to batch and cache database calls. But in some cases, even this is enough and the only solution is to block queries by calculating a maximum execution cost or query deep. And any of these solutions will depend on the library you’re using.

2. REST can do much of what GraphQL does

GraphQL is an alternative to REST for developing APIs, not a replacement.

The main reason why you would use GraphQL is to send a query specifying only the information you need and receive exactly that. But you can also achieve this using REST by passing the name of the fields you want to use in the URL (implementing the parsing and returning logic yourself):

GET /books/1492030716?fields=title,pageCount

This is easy to implement; there are many JSON API libraries in many languages. If you want the benefit of using a schema and strong types in REST, you can use JSON schemas. There are many libraries that implement and support JSON schemas.

If you want to use a query language in REST APIs, a solution such as OData is a great alternative. OData, short for Open Data Protocol, was originally developed by Microsoft in 2007. It’s an open protocol that enables you to create and consume queryable and interoperable RESTful APIs in a simple and standard way.

OData gives you a rich set of querying capabilities and is quickly gaining ground for its open-source approach and exceptional scalability.

The point is that there are valid alternatives, especially for small applications and projects where using GraphQL may be overkill.

By the same token, you’ll run into situations where it would be complicated to implement these libraries and easier to use GraphQL, which natively supports all of these features. But GraphQL can also make things more complicated in its own way, which we’ll discuss next.

3. GraphQL makes some tasks more complex

Using GraphQL in a simple application (for example, one that uses a few fields in the same way, every time) is not recommended because it adds more complexity because of things such as:

  • Types
  • Queries
  • Mutators
  • Resolvers
  • High-order components

Which is not good from a maintenance perspective.

But even if the use of GraphQL is justified, there may be some complications. Two examples are error handling and file uploading.

In REST, checking the response status is the only way to know if the request was executed successfully, if there was a server error, or if the resource was not found. But in GraphQL, you get something similar to the following when an error occurs:

{
  "data": null,
  "errors": [
    {
      "message": "Validation error...",
      "locations": [
        {
          "line": 5,
          "column": 6
        }
      ]
    }
  ]
}

You will have to parse this message to know if there’s an error, and probably different errors will have slightly different formats or add some custom fields.

Some libraries, such as Apollo client, help with handling errors, but not as easily as in a REST API.
File uploading is not part of the GraphQL specification, so the implementation is left to you. Some options include using:

The third option is probably the best. However, it means adding another dependency to manage your project and it may not be available for all programming languages.

4. It’s easier to use a web cache with REST vs. GraphQL

I want to emphasize the web part — caching at the network level — because you can certainly implement a cache at the database level or at the client level with the in-memory cache implementation of Apollo Client.

But a cache implemented at the HTTP level — i.e., with a reverse proxy — that stores the content of a request can reduce the amount of traffic to a server or keep frequently accessed information in a location close to the client (like a content delivery network).

Since a REST API provides many endpoints, you can easily configure a web cache to match certain URL patterns, HTTP methods, or specific resources.

In GraphQL, there’s only one endpoint (usually an HTTP POST endpoint) where all the queries are sent. Since each query can be different, it is harder to use this type of caching. To reduce the amount of traffic to the web server, you can use persisted queries with persistgraphql.

This tool assigns identifiers to GraphQL queries producing a JSON file that maps queries and identifiers. With this map, the client only sends the identifier and the parameters of a query to the server so it can just look it up. However, this adds another layer of complexity, and it only partially solves the problem.

5. GraphQL schemas could be a problem

By allowing you to define a schema, GraphQL gives you a lot of benefits, such as automatic validation and introspection. Depending on how you choose to write or generate your schemas, static schemas could become a problem when you have a changing data model because the response the clients are going to get depends on the schema definition and the query they make.

For example, you cannot have more depth than what is specified in the schema or in the query, schemas that you can modify at runtime, or dynamic type definitions.

You can now solve this problem in GraphQL by building schemas programmatically using a code-first approach. The design process begins with coding the resolvers and the SDL version of the GraphQL schema is generated programmatically.

6. REST is better for error handling and tooling

Error handling in REST is easier when compared to GraphQL. RESTful APIs follow the HTTP spec with regards to resources and returns various HTTP statues for various API request states. GraphQL, on the other hand, returns the 200 Ok status for every API request, including for errors. This makes it difficult to manage errors and makes it hard to integrate with monitoring tools.

Conclusion

GraphQL is a powerful tool, and there are many reasons to choose GraphQL over REST. But don’t forget to choose the right tool for the right job.

The points I have presented here may not always apply, but it is worth taking them into account to see if they can be addressed. There are still use cases where REST is a valid approach.

Monitor failed and slow GraphQL requests in production

While GraphQL has some features for debugging requests and responses, making sure GraphQL reliably serves resources to your production app is where things get tougher. If you’re interested in ensuring network requests to the backend or third party services are successful, try LogRocket.https://logrocket.com/signup/

LogRocket is like a DVR for web apps, recording literally everything that happens on your site. Instead of guessing why problems happen, you can aggregate and report on problematic GraphQL requests to quickly understand the root cause. In addition, you can track Apollo client state and inspect GraphQL queries' key-value pairs.

LogRocket instruments your app to record baseline performance timings such as page load time, time to first byte, slow network requests, and also logs Redux, NgRx, and Vuex actions/state. .
Esteban Herrera Family man. Java and JavaScript developer. Swift and VR/AR hobbyist. Like books, movies, and still trying many things. Find me at eherrera.net

31 Replies to “Why you shouldn’t use GraphQL”

  1. I think all this article did was convince me that REST has hacks for things that GraphQL has natively. You argue, “There are many libraries by way of JSON API and JSON Schema” but when there is a library that solves a pain point for GraphQL your counter point is, “it means adding another dependency to manage your project”.

    Your argument for performance and heavy queries is silly. If someone wants to do a heavy query, it’s more taxing on the server in the REST model because of the network overhead. Neither REST nor GraphQL are going to stop people from doing bad, bloated queries or sets of queries.

  2. This article made myself more convinced to use GraphQL, rather than re-inventing the wheel by implementing your own query language on top of a general REST interface.

  3. Thank you for your perspective, maybe graphql is not yet the best tool in some occasions but it is possible that with the development of this query language in a near future graphql surpass rest, another perspective is given in this article that gives the opinion of using graphql or making co exist with rest https://www.imaginarycloud.com/blog/graphql-vs-rest/.

  4. GraphQL is great etc but there will be certain use cases where REST may be more suitable.
    In my case we have a Java backend ecommerce server that needs to Shopify API (they have REST and GraphQL APIs).
    We GET all orders from a RESTorders endpoint and then UPDATE the status of the orders it’s processed. Same for the inventory REST endpoint.
    For the most part those are the only endpoints our backend system needs to connect to, it can limit the fields it needs to request in the REST query and is unlikely to change the query and updates anytime soon.
    If it used GraphQL it would need to install Ruby, migrate the build from ant to Gradle. So there will be a lot more complexities and additional dependancies to the runtime environment.
    Also we only have dev team, small-ish project and we are consuming not building APIs so no need for the flexibility of GraphQL.
    GraphQL and REST are ultimately tools and every tool has it’s use.

  5. If I had the chance I would explain to every REST designer that this: “GET /books/1492030716?fields=title,pageCount” does NOT scale.

    I’ve been working at a large payroll company where we have canonical representations of human resources which for example represent a ‘worker’. Those schemas are huge. Like 18.000 lines huge. You absolutely 100% don’t successfully whitelist those with a “fields” querysstring item. Nor do you successfully filter them with a $filter querystring item. It’s just too large.

    Graphql is the way to go there.

  6. “It may be done poorly” is not a compelling argument against any particular technology.

    “It adds complexity” can be, but one assumes we are not talking trivial cases in arguments like this, so what’s really necessary is to show whether the complexity is significant on a serious project. GraphQL can drastically simplify the number and complexity of routes, e.g., versus a standard REST project.

    Performance arguments can be as well, but again, you need an apples-to-apples comparison. A big part of the purpose of GraphQL is to eliminate the multiple round-trips. If that’s not a pain point for you, maybe it’s not necessary. But if it is, you’re going to end up building increasing numbers of REST calls to accommodate.

  7. “It may be done poorly” is not a compelling argument against any particular technology.

    I think how frequently is a very important indication if not the most important against a tech stack, i looked at 3 graphQL implementations recently and they were all slow and terrible.

    Something as simple as REST and its still done poorly in say half the cases for something as complex as GraphQL especially ins strongly typed languages id suggest the chance of a good outcome is very low and would certainly need management buy in to have a few goes at getting right.

  8. They more I use graphql the less I like it. So far I couldn’t find anything that graphql does that REST wouldn’t do. Especially sucks java implementation of graphql: starting with outdated documentation and examples ending with their design choice of chain of builders of the builders of the builders… Nice try to generalize queries and put them under one umbrella, but it’s more pain than it’s worth.

  9. having used GraphQL, I see why a lot of new comers won’t bite this article, but in fact if you use it for a while, you’ll see why it can lead to some bloated APIs, moreover, I do think there are better alternatives, besides, think of who created it, Facebook, they created this piece of tech to suite their own needs, which I can argue is not what I would consider a general need, but rather driven by their business requirements. Things like using HTTP status codes, etc, these are important, and can in fact simplify clients significantly, but I guess for those who have not used it really, they won’t know these things, or yet they’ve got to stumble upon them.

  10. Completely agree with Suhail Abood. GraphQL should not be seen as a general purpose REST replacement, which currently seems to be happening a lot. I am working on a new GraphQL API and it is already a big ugly mess with many issues that need to be resolved that would not have existed were it created in REST.

  11. I think getting the full benefits from GraphQL requires a paradigm shift. GraphQL is inherently about type-driven design. It supports algebraic data types and this plays really nicely with functional programming languages that natively support AlgDTs. GraphQL also supports a Functional Domain Driven Design approach.

    Also, if you use a GraphQL endpoint like Hasura, you can create end-to-end modelling of domain entities in your data. Dillon Kearns, a developer who uses Elm, discusses a “types without borders” benefit of GraphQL:
    https://www.youtube.com/watch?v=memIRXFSNkU

    When you take a deep type-driven design approach using AlgDTs as the basis for your data entities you get a whole host of benefits. This comment really says it all:
    https://softwareengineering.stackexchange.com/questions/317587/is-it-still-valid-to-speak-about-anemic-model-in-the-context-of-functional-progr/317599#317599

    Scott Wlashin doesn’t specifically mention GraphQL but everything in his talk is the background for thinking about GraphQL:
    https://www.youtube.com/watch?v=1pSH8kElmM4

    Scott also talks about creating APIs that give consumers feedback about what they can do, rather than just erroring what they can’t:
    https://www.youtube.com/watch?v=fi1FsDW1QeY

    Also, look at Richard Feldman’s talk “Making impossible states impossible”:
    https://www.youtube.com/watch?v=IcgmSRJHu_8

    I think that when you care deeply about type-driven design GraphQL makes a whole lot of sense. Especially if your language supports AlgDTs and type and function composition. As well as immutable data.

    Also check this article out that links GraphQL with CQRS and Event Sourcing:
    https://gist.github.com/OlegIlyenko/a5a9ab1b000ba0b5b1ad

    There is also this awesome article that really helps to put CQRS and Event Sourcing into perspective:
    https://gist.github.com/OlegIlyenko/a5a9ab1b000ba0b5b1ad

    Check out Hasura GraphQL Endpoint:
    https://blog.hasura.io/

    I think GraphQL is just getting started.

  12. “Performance issues with GraphQL queries”

    This is exactly the reason why GraphQL is not bad, IT’S DANGEROUS.

    GraphQL could work fine for small set of data. Some developers think that since they use the cloud then they don’t need a DBA so the end user could exploit the queries as they are pleased… Well, the cloud is metered (also it is not unlimited unless you want to pay really premium for that).

    About DBA, even a server-less configuration needs a DBA (because AWS and Azure makes a poor DBA replacement). And if the project has a DBA, then he (or she) will say “nope!” to GraphQL.

    In any case, it’s not rare to find rookies that does not even know about paging a query, so they load 1 million of rows to simply list 50 rows.

  13. In what possible way is OData worse than GraphQL? It’s far more feature complete, makes all tasks simpler, handles errors beautifully, and handles update and deep inserts/updates seamlessly.

  14. In rest you need to write your api, then write a swagger of the contract, then use a code generator for your client to finally have your api running between your server and client. There is several possible point of failure:
    1. You can easily design your rest api the wrong way
    2. You might be stuck in rest to find the right path url to link 2 or more concepts together
    3. You might introduce mistakes writing the swagger and you need to document both the swagger and your code
    4. Your client api generator might not generate exactly what is inside your swagger dropping some typings
    5. The client generated might implicitly rely on way to post data which your server might not support (I had the problem with form and Autorest for instance)

    With a GraphQL schema at least you do have a typed AND documented contract, thanks to the GraphQL standard your endpoint does not give you a lot for interpretation for your client.

  15. Interesting, looks like we came full circle back to WCF+RIA Services that did SQL queries against WCF Rest services.

  16. Not sure what you’re using, but in DotNet, you just build the service and the swagger is auto-generated. Nothing to keep in sync, no mistakes in swagger.

  17. I feel hate to GraphQL and that someone hasn’t bothered to investigate properly

    Agree with comments here – more reason to use it, than not

    Just implement properly

  18. Instead of only `fields`= why not:

    `include`=
    `exclude`=

    Also 18k LINES in for a “worker” instance?!??! Really?

    Your problem is modeling and design, at many levels, not technology.

  19. Half of these complaints seem to be that GraphQL isn’t conducive to the kinds of bad habits that loose typing tends to bring.

    Am I missing something?

Leave a Reply