Esteban Herrera Family man, #Java and #Javascript developer. #Swift, and #VR/#AR hobbyist. Like #books, #movies and still trying many things. eherrera.net

5 reasons you shouldn’t be using GraphQL

4 min read 1285


GraphQL is great, it allows you to work in a declarative style by enabling you to select only the information or operations that you need.

However, just like any other tool, it’s not a silver bullet.

In this post, I’ll talk about five reasons you shouldn’t use GraphQL when the alternative is a REST architecture:

  1. REST can do much of what GraphQL does
  2. GraphQL will make some tasks more complex
  3. It’s easier to use a web cache with REST than with GraphQL
  4. You could have performance issues with GraphQL queries
  5. The way GraphQL schemas work could be a problem

Of course, these situations may not always apply to your project, but it’s important that you are aware of them and consider the implications.


REST can do a lot of what GraphQL does

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

The main feature of GraphQL is to be able to send a query specifying only the information you need and get exactly that.

But you can also achieve this using REST, from 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

And it is not difficult to implement. There are many JSON API libraries in many languages.

Do you want the benefits of using a schema and strong types in REST?

Use JSON schemas.

There are many libraries that implement and support this specification too.

Do you want to use a query language in REST APIs?

Try OData.

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

Of course, there are situations where it will be complicated to implement these libraries and for those cases, it may be better to use GraphQL, which natively support all of these features.

But GraphQL can also make things more complicated.

GraphQL will make 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, like Apollo client, help with handling errors, but not as easily as in a REST API.

About file uploading, this feature is not part of the GraphQL specification, so the implementation is left to you. Some options are:

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

It’s easier to use a web cache with REST than with 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 (for example 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 (most of the time 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.

One option to reduce the amount of traffic to the web server is the use of 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.

Performance issues with GraphQL queries

By being a query language for APIs, GraphQL 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? Something like “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 just 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 have 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 are not careful, a few big queries can bring your server down to its knees.

In a GraphQL API, there are tools like Dataloader that allow you to batch and cache database calls, but in some cases, even this will not be enough and the only solution will be 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.

GraphQL schemas could be a problem

By allowing you to define a schema, GraphQL gives you a lot of benefits, like automatic validation and introspection.

But schemas are static and 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.

The GraphQL specification doesn’t cover dynamic features like these, so you have to rely on hacky solutions or custom server implementations.

Some libraries like GraphQL Ruby have mechanisms to define your schema dynamically programmatically. This may solve some requirements.

On the other hand, I have seen people create very generic schemas to try to resolve more complex requirements:

type Query {
  request(query: String!): Response
}
 
type Response {
  body: String
}

This comes at the expense of most of the benefits GraphQL.

In these cases, it’s better to stick to REST.

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.

200’s only : 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. eherrera.net

18 Replies to “5 reasons you shouldn’t be using 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.

Leave a Reply