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

5 min read 1418


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.

Sick of debugging web apps? Instead of guessing why errors happen, or asking users for screenshots and log dumps, LogRocket pairs session replay with technical telemetry to quickly understand what went wrong.

Get a Free Trial of LogRocket

or

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.

Plug: LogRocket, a DVR for web apps

https://logrocket.com/signup/

LogRocket is a frontend logging tool that lets you replay problems as if they happened in your own browser. Instead of guessing why errors happen, or asking users for screenshots and log dumps, LogRocket lets you replay the session to quickly understand what went wrong. It works perfectly with any app, regardless of framework, and has plugins to log additional context from Redux, Vuex, and @ngrx/store.

In addition to logging Redux actions and state, LogRocket records console logs, JavaScript errors, stacktraces, network requests/responses with headers + bodies, browser metadata, and custom logs. It also instruments the DOM to record the HTML and CSS on the page, recreating pixel-perfect videos of even the most complex single page apps.

Try it for free.

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

9 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.

Leave a Reply