GraphQL - The good and the bad parts

According to graphql.org, GraphQL is a query language for APIs and a runtime for fulfilling those queries with your existing data. It provides a complete and understandable description of the data in your API, gives clients the power to ask for exactly what they need and nothing more, makes it easier to evolve APIs over time, and enables powerful developer tools.

Why was GraphQL developed?

The question was answered by Lee Byron, in this article.

Back in 2012, we began with making an effort to rebuild Facebook’s native mobile applications.

At the time, our iOS and Android apps were thin wrappers around views of our mobile website. While this brought us close to a platonic ideal of the “write once, run anywhere” mobile application, in practice, it pushed our mobile-web view apps beyond their limits. As Facebook’s mobile apps became more complex, they suffered poor performance and frequently crashed. As we transitioned to natively implemented models and views, we found ourselves for the first time needing an API data version of News Feed — which up until that point had only been delivered as HTML. We evaluated our options for delivering News Feed data to our mobile apps, including RESTful server resources and FQL tables (Facebook’s SQL-like API). We were frustrated with the differences between the data we wanted to use in our apps and the server queries they required. We don’t think of data in terms of resource URLs, secondary keys, or join tables; we think about it in terms of a graph of objects and the models we ultimately use in our apps like NSObjects or JSON. There was also a considerable amount of code to write on both the server to prepare the data and on the client to parse it. This frustration inspired a few of us to start the project that ultimately became GraphQL. GraphQL was our opportunity to rethink mobile app data-fetching from the perspective of product designers and developers. It moved the focus of development to the client apps, where designers and developers spend their time and attention.

Why I love it?

It is fast: Apps which use GraphQL are fast and stable because they control the data they get, not the server.

Get many resources: GraphQL queries access not just the properties of one resource but also smoothly follow references between them. While typical REST APIs require loading from multiple URLs, GraphQL APIs get all the data your app needs in a single request. Apps using GraphQL can be quick even on slow mobile network connections.

One endpoint: GraphQL APIs are organized in terms of types and fields, not endpoints. Access the full capabilities of your data from a single endpoint. GraphQL uses types to ensure Apps only ask for what’s possible and provide clear and helpful errors. Apps can use types to avoid writing manual parsing code.

Sustainability: Add new fields and types to your GraphQL API without impacting existing queries. Aging fields can be deprecated and hidden from tools. By using a single evolving version, GraphQL APIs give apps continuous access to new features and encourage cleaner, more maintainable server code.

Version free: The shape of the returned data is determined entirely by the client’s query, so servers become simpler and easy to generalize. When you’re adding new product features, additional fields can be added to the server, leaving existing clients unaffected. When you’re sunsetting older features, the corresponding server fields can be deprecated but continue to function. This gradual, backward-compatible process removes the need for an incrementing version number. We still support three years of released Facebook applications on the same version of our GraphQL API.

Strongly typed: Each level of a GraphQL query corresponds to a particular type, and each type describes a set of available fields. Similar to SQL, this allows GraphQL to provide descriptive error messages before executing a query. Protocol, not storage: Each GraphQL field on the server is backed by any arbitrary function. While Facebook was building GraphQL to support News Feed, they already had a sophisticated feed ranking and storage model, along with existing databases and business logic. GraphQL had to leverage all this existing work to be useful, and so does not dictate or provide any backing storage. Instead, GraphQL takes advantage of your existing code.

Introspective: A GraphQL server can be queried for the types it supports. This creates a powerful platform for tools and client software to build atop this information like code generation in statically typed languages, our application framework, Relay, or IDEs like GraphiQL GraphiQL helps developers learn and explore an API quickly without grepping the codebase or wrangling with cURL.

Where GraphQL sucks?

Query in Indefinite Depth: GraphQL cannot query in indefinite depth, so if you have a tree and want to return a branch without knowing the depth, you’ll have to do some pagination.

Specific Response Structure: In GraphQL the response matches the shape of the query, so if you need to respond in a very specific structure, you’ll have to add a transformation layer to reshape the response.

Cache at Network Level: Because of the common way GraphQL is used over HTTP (A POST in a single endpoint), cache at the network level becomes hard. A way to solve it is to use Persisted Queries.

Handling File Upload: There is nothing about file upload in the GraphQL specification and mutations don’t accept files in the arguments. To solve it you can upload files using other kinds of APIs (like REST) and pass the URL of the uploaded file to the GraphQL mutation, or inject the file in the execution context, so you’ll have the file inside the resolver functions.

Unpredictable Execution: The nature of GraphQL is that you can query combining whatever fields you want but this flexibility is not for free. There are some concerns that are good to know like Performance and N+1 Queries.

Super Simple APIs: In case you have a service that exposes a really simple API, GraphQL will only add extra complexity, so a simple REST API can be better.

Code sample

Imagine that you have two collections (MongoDB table), “books” and “authors”.

Now, if you want to retrieve some information using the RESTful approach, probably, your requests will look something like that:

website.com/books/:id -> response: title, genre, authorID website.com/authors/:id -> response: name, biography, bookIDs

But, what if we want to retrieve information about each book of an author? Would you like to make a request for each id from the author’s books?

And here GraphQL comes. You may make a request like this:

{
  book(id: 1) {
    title
    genre
    author {
      name
      biography
      books {
        title
      }
    }
  }
}

You request information about the title and the genre of the book with id 1, also you retrieve information about the author, more exactly, name, biography, and title of all books that he has written, all of this by doing a single request.

Also, we can select what information should be returned. For example, I just want the title, the genre, and the author’s name for this book.

{
  book(id: 1) {
    title
    genre
    author {
      name
    }
  }
}