The Falcor data model is a graph, and the GraphQL data model is a tree.

Caleb Meredith
EdgeCoders
6 min readJul 7, 2016

--

Half a year ago Netflix and Facebook convinced me that REST is no longer the ideal architecture for building maintainable apps. We can’t waste our users time sending around “large-grained” data through our APIs, we need to optimize for efficiently delivering “small-grain” “nuggets” of data to our user interfaces.

Netflix and Facebook convinced me through their own respective answers to this problem: Falcor and GraphQL.

The ideas and motivations are very similar between these two API architectures, so what’s the difference? Well ultimately I’ve narrowed the difference down into one ironic statement:

The Falcor data model is a graph, and the GraphQL data model is a tree.

Oh the classic GraphQL is not a graph paradox.

So let me explain the fundamental difference between Falcor and Graphql. Then I’ll give my own answer to the question: “which architecture is best for my app?” (spoilers: I don’t agree with Jafar Husain).

You’ll need to have a basic understanding of these architectures before we continue. If you don’t have that, I recommend you watch the following talks:

Also, both the GraphQL and Falcor websites have a very strong pitch for their respective architectures if you still don’t understand.

Alright, enough introductions, let’s talk abstractions.

Falcor

Out of the two Falcor was my first love. It’s existance was validation of an idea I had explored before. That idea being it is both possible and desireable to represent your entire data universe as a really big JSON object.

This idea was pretty seductive to me for a while. Just try this, If you squint hard enough, a well designed REST API easily looks like an extra layer on top of a really big JSON object. For example URLs like:

Could be easily represented in JSON:

So that’s the mental model I’d use to build my REST APIs for a while.

Falcor takes this idea of your data being one big JSON object but throws away the old RESTful idea of a single-resource-to-URL mapping and therefore the requirement of multiple HTTP requests. Instead Falcor takes the large JSON object approach to data modelling and provides a cleaner, faster, and more declarative API.

But Falcor does keep the idea of a “path.” That’s how we are able to traverse our large JSON object, by paths. The path is as much Falcor’s query language as the GraphQL is well—GraphQL’s query language.

The second feature of Falcor that makes it akin to our REST APIs is the ability to have references. While Falcor represents your entire data as a large JSON object which is therefore inherently a tree, Falcor actually considers your data to be a “graph.” That’s what references allow.

So what’s even the difference between a tree and a graph? In academic terms, a tree is just a graph with no cycles. I know that makes lots of sense. The best way to understand the difference is visually. If you can’t see the two images below try to understand from the Wikipedia articles I linked earlier:

A tree. Note how there are no cycles.
A graph. Note how there are cycles.

JSON will always be a tree, that’s how the data format was designed. However, in order for Falcor to be awesome, the data needs to be a Graph. Falcor accomplishes this by references:

…and in REST world, a “ref” would just be a 303 redirect. This is why we say the data model of Falcor is a graph.

These two architecture constructs, the path and the reference, have serious positive benefits for Falcor.

The first is streaming. Because data is identified in Falcor with a unique JSON path, it is easy to merge the data in separate chunks. For example, a Falcor server could return a user object, which the UI could use to start rendering the UI. Then a little later Falcor could send down the user’s posts which would be used to continue rendering the API. By that point, however, the UI would already be responsive to user interactions.

The second is very similar, live updates. Similar to streaming, the path construct allows us to easily merge in live data from the server as it comes.

The third benefit you get from paths and references is caching. Most importantly you get caching and consistency without needing to define any special “Node” type or “id” field as GraphQL frameworks like Relay and Apollo must do. For Falcor, the “id” is just the path, and the data comes pre-normalized because of references. You don’t need the extra code of a framework for efficient data fetching with Falcor.

Vanilla GraphQL gets none of these benefits.

GraphQL

If you watch Laney Kueznel and Lee Byron’s talk at React Europe 2016 where they talk about both streaming and live updates (that we now know Falcor gets for virtually free) it is easy to see that GraphQL has fundamental problems on an abstraction level. Falcor is strictly a higher level abstraction.

So why can’t we use paths in GraphQL for smart merging strategies like in Falcor? The answer is in the sample query on the GraphQL homepage:

…and then the response:

In case you can’t see it, you can blame arguments. In the quest for a good developer experience GraphQL loses the ability to uniquely identify our data by paths like Falcor. This is why GraphQL needs the Relay Object Identification specification.

However, despite losing in the streaming/realtime arena, GraphQL wins big in practicality. Mutations, directives, fragments, and most importantly a type system give an incredible user experience to both small and large teams alike. All these things can be emulated in Falcor, but being first-class language features makes GraphQL much more practical for API use out of the box.

Conclusion

So which is best for your app? Falcor or GraphQL?

The popular story is that GraphQL is more complex thanks to its schema overhead and should therefore be used in more complex apps whereas Falcor is more general and should be used for simpler apps with faster iteration cycles. At least this is the advice Jafar Husain of Falcor gave. However, I don’t agree with his conclusions. I’m a big fan of Jafar and Falcor (in case you hadn’t already seen), but the question of “Falcor vs. GraphQL” doesn’t boil down to GraphQL’s type system because the types don’t necessarily add any extra complexity to the API definition. Rather the question is about the level of abstraction.

GraphQL has an introspectible type system, and as such it gives the average user much more for less. Therefore it is the ideal for apps where speed to market is important. GraphQL is also much more mature at the moment, and you can be guaranteed your API will still be in a semi-healthy state after a few months with little effort thanks to the constraints of GraphQL.

Falcor doesn’t have a type system making it more dynamic and less prescriptive. A more “pure” abstraction if you will. Therefore, Falcor is best used for teams who need a more flexible solution and aren’t afraid to build more themselves. Also, Falcor may be the best option for apps where data streaming and/or real time capabilities is a major part of the app (this may change in the future).

So in summary:

  • GraphQL is more practical than Falcor.
  • Falcor is a better abstraction than GraphQL.

As a final note: For the moment, I always recommend GraphQL, just for the reasons stated above. In addition I’m a huge GraphQL fan, just as much as I am a Falcor fan. I’m really rooting for both architectures. GraphQL may have a better developer experience than Falcor, but I believe Falcor will ultimately provide the better user experience assuming Netflix steps up its open source game. For most small apps though the difference is imperceivable and already a huge step up from REST. That’s why I default to GraphQL, and I recommend you should to. Just know the limitations and other options of the technology you choose.

--

--

Caleb Meredith
EdgeCoders

Product engineer at Airtable. Previously Facebook. @calebmer on Twitter