March 25, 2016

GraphQL vs. Falcor

Jonas Helfer
Backend

If you’ve been reading other stories in our publication “Building Apollo”, you’ve already heard about GraphQL. What you may not have heard of is Falcor. Falcor — a library for data fetching developed by Netflix — is often compared to GraphQL, because they both try to tackle the same problems, but in different ways. In this post, I want to explore the similarities and differences between GraphQL and Falcor.

By the end of this post, you’ll know:

  • What GraphQL and Falcor are
  • What problem they are both trying to solve
  • What their similarities and differences are
  • Why you could implement left-pad (and other functions) only in one, but not the other (see the example).

If you don’t want to read the whole article, scroll down to “Quick Summary” for the tl;dr.

I’m more familiar with GraphQL than Falcor, but I find them both to be really amazing, and I’ll do my best to cover them equally well.

Ready to find out more? Let’s get started!


The problem they solve

On a high level, both Falcor and GraphQL were designed to solve the same problem — managing the increasingly complex data requirements of modern web/mobile apps.

The best practice for web development has changed significantly over the last few years. While just a few years ago most websites used to be rendered on the server and have only relatively little client-side logic, the opposite is true of new apps today. Single-page applications and clients that implement complex logic are the new reality.

In a Ruby app, your model, your view, and your controller all live on the server. Getting data from your models to your view is not an issue, because almost all the data is right there on the server, where the page is rendered. In modern javascript apps, that is no longer the case: Your controllers and your views now live mostly on the client, but most of the data is still on the server.

With all but the most custom RESTful APIs, fetching data from the server is both costly and complicated: the latency is high, and chances are you will either fetch more data than you need or make more roundtrips you would like — or both! That’s where GraphQL and Falcor come to the rescue.


Falcor in a nutshell

Falcor has a very simple premise: All of your data is represented as one giant JSON model, and you code the same way whether your data is on the client, or on the server (Falcor will figure it out for you).

To get around the most basic limitations of JSON, Falcor extends it to include references, which just means that JSON can now also represent circular data structures, like graphs. You can query it like so:

// ask for name and age of user with id = 5
model.get("users[5]['name','age']");// which will eventually return something like
{
  "users": {
    "5": {
      "name": "John Doe",
      "age": 33
    }
  }
}// you can also ask for ranges
model.get("users[5..7].name);// which eventually returns the following
{
  "users": {
    "5": { "name": "John Doe" },
    "6": { "name": "Jane Doe" },
    "7": { "name": "Mary Poppins" }
  }
}

Falcor then takes care of merging together the requests for all the data your templates need into a single query, and makes sure to only fetch each item once, even if it’s used in multiple places. It also caches it for you in the client, in case you need it again later.

At this point, you’re probably wondering whether all your data has to be stored in JSON, right? That’s where the other part of Falcor comes in: routes. On a Falcor server, you define routes, which match certain paths that can be requested. For example, you could define a route which matches the “users” model from the previous example. How that route gets its data is entirely up to you — it might come from a SQL database, a microservice, or even an external API.

Next, let’s take a look at GraphQL.


GraphQL in a nutshell

Unlike the name suggests, GraphQL is not a query language for graph databases. It’s a declarative, strongly typed application-level query language. GraphQL fits between your backend and your frontend. It lets you define a model for your data, and a mapping between that model and your backends.

Here’s how you would write the example queries from above in GraphQL:

graphql.query(`
{
  user(id: 5){
    name
    age
  }
}
`);// returns the following
{
  "user": {
    "name": "John Doe",
    "age": 33
  }
}// query for a range
{
  users(first: 3, after: 4){
    id
    name
  }
}// returns the following
{
  "users": [
    { "id": 5, "name": "John Doe" },
    { "id": 6, "name": "Jane Doe" },
    { "id": 7, "name": "Mary Poppins" }
  ]
}

As you can see, the shape of the query closely matches the shape of the data.

GraphQL only defines the query language, and not the actual implementation. It also doesn’t encompass client side tools for query merging, caching and all that fancy stuff. Those are handled by a client-side GraphQL library like Relay. More on that later…

If you want to know more about GraphQL, here’s a short intro post that I wrote a few weeks ago.

Similarities

GraphQL and Falcor have many similarities, these are just a few of them:

As you can see, both GraphQL and Falcor are a layer between your front-end and your backends, neither of them is a replacement for your existing backend.

They have a different syntax, but similar semantics for declaring exactly what data your views need.

Both Falcor and GraphQL (+Relay) fetch your data in one call to the server instead of many, and they cache the data for you.

Differences

Falcor and GraphQL have a lot of similarities, but they also have some significant differences:

While Falcor is easier to learn and write, GraphQL has a steeper learning curve, but is more powerful.

GraphQL has a schema and static types, Falcor does not have that. There is currently no easy way (that I know of) to tell what type of data your Falcor will return to you.

GraphQL has schema introspection built-in, which allows for some very nice tooling, like GraphiQL. The Falcor docs say that if you know your data, you know your API, but the problem is that often we don’t actually know the data (what was that field called again??), and it would be great if there was some way to explore it. GraphiQL makes that very easy, and it could be integrated directly into your IDE of choice.

GraphQL lets you provide arguments to queries, with Falcor you’re limited to IDs and explicit ranges. That means you can’t implement a search function, a custom sort, or even left-pad (sorry… I couldn’t help it…) on the server.

Check out the left-pad example in GraphQL, and play around with it!

On the other hand, Falcor has built-in set and get operations with straight-forward cache semantics, while GraphQL doesn’t provide that.

GraphQL has an increasingly active ecosystem, with implementations in Java, Python, Ruby, Scala, .NET, Go, etc. As far as I can tell, there are no implementations of Falcor other than the JavaScript one by Netflix. That means if you want to build anything other than a web application with a Node.js server, you’re on your own. [update : there is a .NET router for Falcor on GitHub in “developer preview”, but currently (May 2016) the last commit is from Nov 2015]

By now you can probably see a pattern: Falcor has many features included, is easy to learn, but limited in scope. GraphQL is more powerful, but has a steeper learning curve and requires you to make more choices yourself.

Interesting fact: You could implement all of Falcor in GraphQL (but not the other way round). In fact, Huey Peterson has already done something similar here.


Quick Summary (tl;dr)

To summarize, here are the pros and cons that I see at the moment with GraphQL and Falcor:

Falcor Pros:

  • Really straight forward, easy to learn
  • Things like caching and query-merging included

Falcor Cons:

  • Not as powerful as GraphQL (no arguments)
  • No built-in model/schema introspection
  • No implementations other than JavaScript, and little visible traction

GraphQL Pros:

  • Very powerful and flexible
  • Static types and introspection — GraphiQL FTW
  • Many implementations in other languages, growing community

GraphQL Cons:

  • Steeper learning curve
  • No batteries included. Fair amount of assembling required
  • Relay (Javascript GraphQL client) has a steep learning curve

Conclusion

In my opinion, both GraphQL and Falcor are great solutions, and which one is better depends on the application. If your app doesn’t need anything that Falcor doesn’t already provide, you should probably pick Falcor. If you want to keep the flexibility of using more powerful features either now or later, or want to use it in languages other than JavaScript, GraphQL is most likely the best choice.


We could leave it at that, but wouldn’t it be great if we could bring the simplicity of Falcor to GraphQL, without having to give up any of its power?

That’s exactly what we’re doing with Apollo: we’re building a data stack based on GraphQL that will be as easy to learn and use as Falcor, but with all the power of GraphQL at your disposal when you need it. Like Meteor, Apollo will be zero-boilerplate, no-nonsense and quick to set up, but with all the flexibility of a library that you can just plug in to work with your existing app!

We’re just a few days away from showing you our first demo of Apollo, so make sure to subscribe if you don’t want to miss it!

If you’re curious, you can read more on our Medium publication Building Apollo.

Written by

Jonas Helfer

Stay in our orbit!

Become an Apollo insider and get first access to new features, best practices, and community events. Oh, and no junk mail. Ever.

Similar posts

June 17, 2020

Register Schema Changes Automatically with Schema Reporting

by Ran Magen

Company