Just Because Github Has a GraphQL API Doesn’t Mean You Should Too

Recently there has been a lot of talk about Facebook’s GraphQL specification, and exactly how it transforms the way applications are now able to interact with each other. In fact, its virtues have become the subject of debate with Kin Lane, publisher of APIEvangelist.com saying GraphQL Seems Like We Do Not Want To Do The Hard Work Of API Design and Apollo’s Sashko Stubailo offering a rebuttal claiming that GraphQL is actually the next generation of API design. Meanwhile, Github has given a major endorsement to the spec, recently indicating that GraphQL will play a major role in the future of its platform.

To be clear, GitHub is not actually replacing their existing REST or Push (Webhooks) APIs, as confirmed by ProgrammableWeb editor-in-chief David Berlind.  But with Facebook and GitHub now pushing GraphQL, is the tide unjustifiably switching away from REST?  Should you follow?

Query languages, of which GraphQL is one, are not a new technology, or even a new idea.  Instead, as both Facebook and GitHub point out, it is a solution to a problem they are currently experiencing - a solution they came to by disregarding several key principles behind REST, key ideas that were implemented to solve other problems that were being experienced.

In the GraphQL vs REST debate, somehow this aspect seems to get lost completely.  GraphQL and REST are designed to solve different challenges - different problems.  GraphQL is designed specifically to allow the querying of data models, while REST is designed to act in a similar fashion to the semantic Web - allowing us to have agile, changing, and versionless APIs.

In many respects, that means when we are comparing GraphQL to REST, we are comparing apples to oranges.  Just as when we compare MySQL to MongoDB - both have strengths and weaknesses (if you don’t believe me, just listen to the sales teams for each).

Where GraphQL Shines

Unlike REST, GraphQL is designed to access multiple resources simultaneously.  This means that you are not only able to be more precise in not only retrieving just the data you desire (something that is built into some of today’s modern RESTful APIs), but you are able to do so across multiple resources/ data models (with data joins automatically built in) in a single HTTP (or other applicable protocol) call.

GraphQL is also designed to be incredibly structured (so much so that the order of properties in the response is critical).  This means clients will know exactly what to expect (and in what types) without having to pull in JSON or XML schemas.  It also means the API is much easier to document as the possibilities are limited to its models, not its representations and dynamically managed relationships.

Where REST Shines

REST isn’t designed to be model oriented, or a query language, but rather to be an abstraction or representation of the underlying data systems.  However, while many of the differences between REST and GraphQL focus on solving the same problems, REST specifically is designed for the separate evolution of the client and server - with the concept that one can continue to evolve and change WITHOUT impacting the other (something that we have not quite mastered on the REST side).

REST is also designed to provide a uniform interface between the client and the server - meaning that the client and server should be able to communicate in the same manner or in the same format.  Where-as a well built REST API should have the ability to support multiple content-types (XML, JSON, whatever the future may hold), GraphQL requires the use of the GraphQL format regardless of what content type the user is working with (note, GraphQL does support multiple content-types as well, although JSON is listed as the preferred format - a preference  that REST avoids).

Another area where REST excels in its ability to provide error and response feedback, utilizing the HTTP Status Codes and descriptive error messages (Google Errors, vnd.error, JSON API Errors) when used over the Hypertext Transfer Protocol.  This allows the server to inform the client of key components (created, updated, not modified, not found, gone, etc).  Whereas searching for an item that was deleted in GraphQL does not in itself inform the user of any past actions or pending states, but rather returns no results.

But perhaps the most important benefit of REST, one that’s lost in GraphQL is HATEOAS.  Hypermedia as the Engine of Application State was specifically designed to eliminate the rules engine from needing to exist on the client side - rather acting as a way to represent object state in a stateless environment.

It’s just as important to note that there is a huge difference between an API that utilizes hypermedia (ie we quickly implemented HAL, JSON API, JSON-LD, etc) and an API that is hypermedia driven (ie the links dictate the actions you can take, such as with StormPath’s API).

Arguably, most “REST” APIs fail to fully understand this context, and those that do create the very problem that GitHub is trying to solve with GraphQL - multiple HTTP requests to do one thing.  However, by removing HATEOAS from the equation, again GraphQL has tightly coupled the client to the server, meaning the server’s rules cannot evolve without breaking the clients’.

So Which is Better?

Like the Java vs Node.js debate that occurred at API:World, the answer shouldn’t be based on personal preference, but rather on business needs.  The same holds true with the GraphQL and REST debate.  Neither one of these formats are perfect in their current form - and both are trying to solve very specific problems for their organizations.

In the case of Facebook, where they control both the client and server (ie their mobile API and their mobile application) the utilization of GraphQL makes perfect sense.  Because their GraphQL API is not available to public developers, they can afford to change the server without impacting the mobile client too greatly - and if they do, they can work with their respective teams to find work-arounds/ fix any potential blockers.

GitHub likewise wanted an option to reduce HTTP calls (60% of requests to their database tier), and have an easier format to document their API from their code (a different issue altogether).  To do this they drew many similarities between their REST API and their GraphQL API, and ultimately decided that the benefits of their REST implementation did not outweigh an GraphQL implementation in all circumstances

However, that does not mean that in GitHub’s case, pushing out a public GraphQL API was the right choice. In an effort to reduce calls, they are giving up the very layers of flexibility that I believe will drive future APIs.  In essence, they chose a solution to one problem they were facing, but in doing so disregarded solutions for the problems REST was designed to solve - harkening back into a more SOAP like structure (not so much in the sense of classes and methods, but in the strict sense of being tightly coupled to the server’s architecture and underlying models).

Again, arguably you could say that REST runs into the same issues - and there is some truth to that, although more so due to our lack of understanding of proper implementation.  Likewise, you could also treat SOAP as an interface, however it requires a lot more work on the server side to maintain the perceived abstraction.

Is there a Better Way?

Let me be clear in saying that again, you shouldn’t choose any format without first researching and evaluating your needs. With GitHub’s decision, I trust that there are multiple justifications within the business for the launching a GraphQL endpoint.  Multiple reasons to forego the benefits of REST with an API that inevitably tightly couples any consumers and constrains their flexibility to freely change the API in the future.

As such, it’s important to note that while this may be the best interim decision for GitHub, it may not be the best way.  And it may not be the way forward long-term (GraphQL could absolutely be the future, I’ve been wrong before - I just do not see it happening in it’s current form).

Instead, I think REST is already starting to transition towards solving its own problems.  Hypermedia languages are moving more towards being action driven instead of resource driven - meaning they provide more information that allows the machine to present the information dynamically instead of requiring careful user implementation in each case.  This can be seen with two newer specifications: Siren and CPHL.

At the same time, as HATEOAS becomes more used within RESTful APIs, more and more leaders are focusing on reducing the need for API calls.  About two years ago, Owen Rubel proposed a concept of API Chaining, of which I’ve adapted as my own brainstorming document - a way to make one HTTP call across multiple resources - and retrieve just the data you need back - while also respecting the server’s rules and dynamically pulling in resources via the hypermedia links.

Early benchmarks tested against idea have not only been able to successfully handle multiple resource calls with a single HTTP request, but significantly reduce the processing time required.  Using chaining when attempting three calls has shown a reduction of up to 66%, or a speed increase of between 0.2 and 0.8 seconds over making the three calls individually.

Then there is also the sixth constraint of REST, which very few people are talking about.  Code on Demand - a way to for the client to be self-updating, self-evolving - allowing the server to break backwards compatibility without breaking backwards incompatibility.

Fielding has always envisioned a versionless API.  An API that could evolve in a way similarly to the Web itself.  GraphQL, while an incredible tool with many valuable use cases, takes us further away from that vision.

Learn more about RESTful API Design and Hypermedia in my book, Undisturbed REST: a Guide to Designing the Perfect API

Be sure to read the next Webhooks article: How to Use Webhooks to Recover Subscription Customers


Comments (10)


Technically, the document should hold ALL IO state (which is why I call the document 'IO State') because API Chaining requires full abstraction of API functionality from business logic. This allows for all IO data checks at any point in the architecture and synchronization of said data across entire architecture.

As it applies to API Chaining, said data allows relationships to be built dynamically once loaded at runtime.

But it appears that you are doing a level of abstraction and that does allow for the API Chaining. My only objection is when people start 'hard coding the chains. Thats when I object and say this is not API chaining because there is no 'dynamism' and the chains cannot be dynamically built based on the data's key relationship.


I agree comparing REST and GraphQL is like comparing apples and oranges. However, as someone who has used a lot of REST APIs, I often feel like I am trying to make orange juice and everybody keeps giving me apples. I wouldn't want to encourage anybody to offer their API only in GraphQL, but as an alternative format to REST I find it a welcome relief.


Well its the difference between tooling and implementation.

A VENDOR  can supply a TOOL but if the pattern/framework makes it easy to implement, tools are unnecessary and/or redundant.

And most people don't understand that the API pattern as we know it was designed for centralized architectures... not distributed architectures. The API Chaining pattern is built on the NEW API Pattern which is built for distributed architectures.

I will be contributing an article on this shortly.


I don't see how REST has any advantage over GraphQL in the sphere of client-server compatibility, which was a major point of this article. In practice, REST APIs endpoints are almost always hard-coded somewhere in the client, not discovered dynamically.


The API pattern binds communication logic/data to business logic creating an architectural cross cutting concern in distributed architectures and making redirects create a secondary request/response. Abstracting the communication logic/data from the business logic allows us to create a communication layer so that communication can be shared and thus redirects to separate api calls can use the original request.

This cuts down on I/O overhead and one can use easily use dynamic relations. See recent talk from RestFest, APIWorld, SpringOne, etc on API Chaining https://www.slideshare.net/bobdobbes/api-chainingtm


It's pretty obvious what's going on here. Mulesoft has built a monolithic business that is fundamentally dependent on REST APIs. GraphQL is a threat to the foundation of their business, and this is a marketing ploy to convince people old technology is the way to go.

You can tell by how it's written. "To do this they drew many similarities between their REST API and their GraphQL API, and ultimately decided that the benefits of their REST implementation did not outweigh an GraphQL implementation in all circumstances." What benefits? That's like comparing the benefits of driving a car with wooden wheels versus a car with rubber tires. "It looks vintage!"

Your main point is that you can't version GraphQL. What makes you think versioning is the best way to handle changes? In REST, if you change the version, you must adopt the new schema in its entirety. In GraphQL, additive changes make it possible for the client to adopt individual changes if/when they're ready, regardless of the order in which the change occurred. Versioning may seem more intuitive, but it's actually exponentially more expensive, and the people at GraphQL recognized this. And on top of that, nothing prevents you from versioning in GraphQL like you would in REST if you really wanted. In fact, nothing prevents you from using GraphQL like a REST API in general! It's just an HTTP GET or POST call with a more structured body! I suggest you read more. https://github.com/facebook/graphql/issues/175#issuecomment-218292957

Play again.


Mr Stowe may have written this article a long time ago but he based it on my work which is open sourced.

Let me point out several things: GraphQL knits calls together so it has overhead. So if you have endpoints attached to resources and GraphQL is knitting those resources together, it does this by making multiple api calls on the backend to knit them. This has VERY high I/O if you understand how redirects are handled.

The api chaining(tm) pattern based on the new api pattern which abstracts the communication layer from business logic allows redirects to happen WITHOUT reissuing the request/response so it can be reused (unlike in GraphQL which has to reissue for every additional resource/endpoint it calls).

This optimization increases speed by by 180% over normal API's (which even GraphQL is slower than)


michaelcbrook - That's a pretty bold claim that MuleSoft somehow influenced my post to ensure that it "met their narrative."  It is even more impressive, since I am no longer with MuleSoft, yet continue to stand by this and am even speaking on it today.

REST and GraphQL are two very different methods for retrieving data.  They are also contradictory (REST has six constraints, five which are required including a uniform interface - which means that you can't technically use GraphQL in a REST API -- that doesn't mean you can't create a hybrid, but it's not the same).

Now that doesn't mean GraphQL is a bad thing, but rather that like ANY technology there are situations where it will excel, and situations where it may be risky or detrimental (especially being a new, untested technology... and yes you'll say Facebook, but my point is that GraphQL has only recently made its debut as a public API, and as such, there hasn't been enough time to thoroughly test it).

I also don't understand your point on versioning, as GraphQL itself has NO versioning mechanism other than a deprecation flag that hides the property from the explorer for FUTURE integrations.  Note - I also talk about the cost of versioning, and the reality is that you have to version your GraphQL API even if you don't call it "versioning" (ie GitHub introducing backwards compatibility breaks that require 3 months notice for developers to update).  While you may be able to minimize your team's development costs by not versioning (or just introducing breaks), there is still a real cost to your consumers.

In certain circumstances, or circumstances where you control the client and the server this is fine.  Facebook is a GREAT example of this where I think GraphQL makes perfect sense.  But in multi-tenant mission critical uses where teams may not have the ability to make those updates in a timely fashion, it doesn't fly.



Its worth noting that the 2013 invention of 'API Chaining' by Owen Rubel (which is a derived pattern of the NEW API Pattern) was nominated for an award at this years APIWorld.

What Mr Stowe implements (and refers to) is more commonly referred to as METHOD CHAINING wherein the request /response are REISSUED and NOT SHARED; one can forgive Mr Stowe on his ignorance in this as many developers make this mistake and as a result have high IO overhead as a result.