Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the difference between Falcor and GraphQL?

People also ask

What is Falcor JS?

Falcor lets you represent all your remote data sources as a single domain model via a virtual JSON graph. You code the same way no matter where the data is, whether in memory on the client or over the network on the server.

What is difference between GraphQL and GraphiQL?

Developers describe GraphiQL as "An in-browser IDE for exploring GraphQL". An in-browser IDE for exploring GraphQL. On the other hand, GraphQL is detailed as "A data query language and runtime".

Does Netflix use GraphQL?

The DGS framework project started at Netflix in 2019 as internal teams began developing multiple GraphQL services. As 2020 wrapped up, Netflix decided to open source the framework and build a community around it.

What does GraphQL do?

GraphQL is designed to make APIs fast, flexible, and developer-friendly. It can even be deployed within an integrated development environment (IDE) known as GraphiQL. As an alternative to REST, GraphQL lets developers construct requests that pull data from multiple data sources in a single API call.


I have viewed the Angular Air Episode 26: FalcorJS and Angular 2 where Jafar Husain answers how GraphQL compares to FalcorJS. This is the summary (paraphrasing):

  • FalcorJS and GraphQL are tackling the same problem (querying data, managing data).
  • The important distinction is that GraphQL is a query language and FalcorJS is not.
  • When you are asking FalcorJS for resources, you are very explicitly asking for finite series of values. FalcorJS does support things like ranges, e.g. genres[0..10]. But it does not support open-ended queries, e.g. genres[0..*].
  • GraphQL is set based: give me all records where true, order by this, etc. In this sense, GraphQL query language is more powerful than FalcorJS.
  • With GraphQL you have a powerful query language, but you have to interpret that query language on the server.

Jafar argues that in most applications, the types of the queries that go from client to server share the same shape. Therefore, having a specific and predictable operations like get and set exposes more opportunities to leverage cache. Furthermore, a lot of the developers are familiar with mapping the requests using a simple router in REST architecture.

The end discussion resolves around whether the power that comes with GraphQL outweighs the complexity.


I have now written apps with both libraries and I can agree with everything in Gajus' post, but found some different things most important in my own use of the frameworks.

  • Probably the biggest practical difference is that most of the examples and presumably work done up to this point on GraphQL has been concentrated on integrating GraphQL with Relay - Facebook's system for integrating ReactJS widgets with their data requirements. FalcorJS on the other hand tends to act separately from the widget system which means both that it may be easier to integrate into a non-React/Relay client and that it will do less for you automatically in terms of matching widget data dependencies with widgets.
  • The flip side of FalcorJS being flexible in client side integrations is that it can be very opinionated about how the server needs to act. FalcorJS actually does have a straight up "Call this Query over HTTP" capability - although Jafar Husain doesn't seem to talk about it very much - and once you include those, the way the client libraries react to server information is quite similar except that GraphQL/Relay adds a layer of configuration. In FalcorJS, if you are returning a value for movie, your return value better say 'movie', whereas in GraphQL, you can describe that even though the query returns 'film', you should put that in the client side datastore as 'movie'. - this is part of the power vs complexity tradeoff that Gajus mentioned.
  • On a practical basis, GraphQL and Relay seems to be more developed. Jafar Husain has mentioned that the next version of the Netflix frontend will be running at least in part on FalcorJS whereas the Facebook team has mentioned that they've been using some version of the GraphQL/Relay stack in production for over 3 years.
  • The open source developer community around GraphQL and Relay seems to be thriving. There are a large number of well-attended supporting projects around GraphQL and Relay whereas I have personally found very few around FalcorJS. Also the base github repository for Relay (https://github.com/facebook/relay/pulse) is significantly more active than the github repository for FalcorJS (https://github.com/netflix/falcor/pulse). When I first pulled the Facebook repo, the examples were broken. I opened a github issue and it was fixed within hours. On the other hand, the github issue I opened on FalcorJS has had no official response in two weeks.

Lee Byron one of the engineer behind GraphQL did an AMA on hashnode, here is his answer when asked this question:

  • Falcor returns Observables, GraphQL just values. For how Netflix wanted to use Falcor, this makes a lot of sense for them. They make multiple requests and present data as it's ready, but it also means that the client developer has to work with the Observables directly. GraphQL is a request/response model, and returns back JSON, which is trivially easy to then use. Relay adds back in some of the dynamicism that Falcor presents while maintaining only using plain values.
  • Type system. GraphQL is defined in terms of a type system, and that's allowed us to built lots of interesting tools like GraphiQL, code generators, error detection, etc. Falcor is much more dynamic, which is valuable in its own right but limits the ability to do this kind of thing.
  • Network usage. GraphQL was originally designed for operating Facebook's news feed on low end devices on even lower end networks, so it goes to great lengths to allow you to declare everything you need in a single network request in order to minimize latency. Falcor, on the other hand, often performs multiple round trips to collect additional data. This is really just a tradeoff between the simplicity of the system and the control of the network. For Netflix, they also deal with very low end devices (e.g. Roku stick) but the assumption is the network will be good enough to stream video.

Edit: Falcor can indeed batch requests, making the comment about the network usage inaccurate. Thanks to @PrzeoR


UPDATE: I've found the very useful comment under my post that I want to share with you as a complementary thing to the main content: enter image description here

Regarding lack of examples, you can find the awesome-falcorjs repo userful, there are different examples of a Falcor's CRUD usage: https://github.com/przeor/awesome-falcorjs ... Second thing, there is a book called "Mastering Full Stack React Development" which includes Falcor as well (good way to learn how to use it):

enter image description here

ORGINAL POST BELOW:

FalcorJS (https://www.facebook.com/groups/falcorjs/) is much more simpler to be efficient in comparison to Relay/GraphQL.

The learning curve for GraphQL+Relay is HUGE: enter image description here

In my short summary: Go for Falcor. Use Falcor in your next project until YOU have a large budget and a lot of learning time for your team then use RELAY+GRAPHQL.

GraphQL+Relay has huge API that you must be efficient in. Falcor has small API and is very easy to grasp to any front-end developer who is familiar with JSON.

If you have an AGILE project with limited resources -> then go for FalcorJS!

MY SUBJECTIVE opinion: FalcorJS is 500%+ easier to be efficient in full-stack javascript.

I have also published some FalcorJS starter kits on my project (+more full-stack falcor's example projects): https://www.github.com/przeor

To be more in technical details:

1) When you are using Falcor, then you can use both on front-end and backend:

import falcor from 'falcor';

and then build your model based upon.

... you need also two libraries which are simple to use on backend: a) falcor-express - you use it once (ex. app.use('/model.json', FalcorServer.dataSourceRoute(() => new NamesRouter()))). Source: https://github.com/przeor/falcor-netflix-shopping-cart-example/blob/master/server/index.js

b) falcor-router - there you define SIMPLE routes (ex. route: '_view.length'). Source: https://github.com/przeor/falcor-netflix-shopping-cart-example/blob/master/server/router.js

Falcor is piece of cake in terms of learning curve.

You can also see documentation which is much simpler than FB's lib and check also the article "why you should care about falcorjs (netflix falcor)".

2) Relay/GraphQL is more likely like a huge enterprise tool.

For example, you have two different documentations that separately are talking about:

a) Relay: https://facebook.github.io/relay/docs/tutorial.html - Containers - Routes - Root Container - Ready State - Mutations - Network Layer - Babel Relay Plugin - GRAPHQL

  • GraphQL Relay Specification
  • Object Identification
  • Connection
  • Mutations
  • Further Reading
  • API REFERENCE

  • Relay

  • RelayContainer
  • Relay.Route
  • Relay.RootContainer
  • Relay.QL
  • Relay.Mutation
  • Relay.PropTypes
  • Relay.Store
  • INTERFACES

  • RelayNetworkLayer

  • RelayMutationRequest
  • RelayQueryRequest

b) GrapQL: https://facebook.github.io/graphql/

  • 2Language
  • 2.1Source Text
  • 2.1.1Unicode
  • 2.1.2White Space
  • 2.1.3Line Terminators
  • 2.1.4Comments
  • 2.1.5Insignificant Commas
  • 2.1.6Lexical Tokens
  • 2.1.7Ignored Tokens
  • 2.1.8Punctuators
  • 2.1.9Names
  • 2.2Query Document
  • 2.2.1Operations
  • 2.2.2Selection Sets
  • 2.2.3Fields
  • 2.2.4Arguments
  • 2.2.5Field Alias
  • 2.2.6Fragments
  • 2.2.6.1Type Conditions
  • 2.2.6.2Inline Fragments
  • 2.2.7Input Values
  • 2.2.7.1Int Value
  • 2.2.7.2Float Value
  • 2.2.7.3Boolean Value
  • 2.2.7.4String Value
  • 2.2.7.5Enum Value
  • 2.2.7.6List Value
  • 2.2.7.7Input Object Values
  • 2.2.8Variables
  • 2.2.8.1Variable use within Fragments
  • 2.2.9Input Types
  • 2.2.10Directives
  • 2.2.10.1Fragment Directives
  • 3Type System
  • 3.1Types
  • 3.1.1Scalars
  • 3.1.1.1Built-in Scalars
  • 3.1.1.1.1Int
  • 3.1.1.1.2Float
  • 3.1.1.1.3String
  • 3.1.1.1.4Boolean
  • 3.1.1.1.5ID
  • 3.1.2Objects
  • 3.1.2.1Object Field Arguments
  • 3.1.2.2Object Field deprecation
  • 3.1.2.3Object type validation
  • 3.1.3Interfaces
  • 3.1.3.1Interface type validation
  • 3.1.4Unions
  • 3.1.4.1Union type validation
  • 3.1.5Enums
  • 3.1.6Input Objects
  • 3.1.7Lists
  • 3.1.8Non-Null
  • 3.2Directives
  • 3.2.1@skip
  • 3.2.2@include
  • 3.3Starting types
  • 4Introspection
  • 4.1General Principles
  • 4.1.1Naming conventions
  • 4.1.2Documentation
  • 4.1.3Deprecation
  • 4.1.4Type Name Introspection
  • 4.2Schema Introspection
  • 4.2.1The "__Type" Type
  • 4.2.2Type Kinds
  • 4.2.2.1Scalar
  • 4.2.2.2Object
  • 4.2.2.3Union
  • 4.2.2.4Interface
  • 4.2.2.5Enum
  • 4.2.2.6Input Object
  • 4.2.2.7List
  • 4.2.2.8Non-null
  • 4.2.2.9Combining List and Non-Null
  • 4.2.3The __Field Type
  • 4.2.4The __InputValue Type
  • 5Validation
  • 5.1Operations
  • 5.1.1Named Operation Definitions
  • 5.1.1.1Operation Name Uniqueness
  • 5.1.2Anonymous Operation Definitions
  • 5.1.2.1Lone Anonymous Operation
  • 5.2Fields
  • 5.2.1Field Selections on Objects, Interfaces, and Unions Types
  • 5.2.2Field Selection Merging
  • 5.2.3Leaf Field Selections
  • 5.3Arguments
  • 5.3.1Argument Names
  • 5.3.2Argument Uniqueness
  • 5.3.3Argument Values Type Correctness
  • 5.3.3.1Compatible Values
  • 5.3.3.2Required Arguments
  • 5.4Fragments
  • 5.4.1Fragment Declarations
  • 5.4.1.1Fragment Name Uniqueness
  • 5.4.1.2Fragment Spread Type Existence
  • 5.4.1.3Fragments On Composite Types
  • 5.4.1.4Fragments Must Be Used
  • 5.4.2Fragment Spreads
  • 5.4.2.1Fragment spread target defined
  • 5.4.2.2Fragment spreads must not form cycles
  • 5.4.2.3Fragment spread is possible
  • 5.4.2.3.1Object Spreads In Object Scope
  • 5.4.2.3.2Abstract Spreads in Object Scope
  • 5.4.2.3.3Object Spreads In Abstract Scope
  • 5.4.2.3.4Abstract Spreads in Abstract Scope
  • 5.5Values
  • 5.5.1Input Object Field Uniqueness
  • 5.6Directives
  • 5.6.1Directives Are Defined
  • 5.7Variables
  • 5.7.1Variable Uniqueness
  • 5.7.2Variable Default Values Are Correctly Typed
  • 5.7.3Variables Are Input Types
  • 5.7.4All Variable Uses Defined
  • 5.7.5All Variables Used
  • 5.7.6All Variable Usages are Allowed
  • 6Execution
  • 6.1Evaluating requests
  • 6.2Coercing Variables
  • 6.3Evaluating operations
  • 6.4Evaluating selection sets
  • 6.5Evaluating a grouped field set
  • 6.5.1Field entries
  • 6.5.2Normal evaluation
  • 6.5.3Serial execution
  • 6.5.4Error handling
  • 6.5.5Nullability
  • 7Response
  • 7.1Serialization Format
  • 7.1.1JSON Serialization
  • 7.2Response Format
  • 7.2.1Data
  • 7.2.2Errors
  • AAppendix: Notation Conventions
  • A.1Context-Free Grammar
  • A.2Lexical and Syntactical Grammar
  • A.3Grammar Notation
  • A.4Grammar Semantics
  • A.5Algorithms
  • BAppendix: Grammar Summary
  • B.1Ignored Tokens
  • B.2Lexical Tokens
  • B.3Query Document

It's your choice:

Simple sweet and short documented Falcor JS VERSUS Huge-enterprise-grade tool with long and advanced documentation as GraphQL&Relay

As I said before, if you are a front-end dev who grasp idea of using JSON, then JSON graph implementation from Falcor's team is best way to do your full-stack dev project.


In short, Falcor or GraphQL or Restful solve the same problem - provide a tool to query/manipulate data effectively.

How they differ is in how they present their data:

  • Falcor wants you to think their data as a very big virtual JSON tree, and uses get, set and call to read, write data.
  • GraphQL wants you to think their data as a group of predefined typed objects, and uses queries and mutations to read, write data.
  • Restful wants you to think their data as a group of resources, and uses HTTP verbs to read, write data.

Whenever we need to provide data for user, we end up with something liked: client -> query -> {a layer translate query into data ops} -> data.

After struggling with GraphQL, Falcor and JSON API (and even ODdata), I wrote my own data query layer. It's simpler, easier to learn, and more equivalent with GraphQL.

Check it out at:
https://github.com/giapnguyen74/nextql

It also integrates with featherjs for real time query/mutation. https://github.com/giapnguyen74/nextql-feathers