You Can't Turn The Network Invisible
Last year, Jafar Husain gave a presentation about Falcor and how Falcor has changed how Netflix handles it APIs. Falcor, like Relay, is a clever bit of programming with an alluring promise to simplify network programming via a powerful abstraction. But we’ve already followed this seductive sirens’ song, many times before, and it usually doesn’t end well.
Object Graphs: The New ORM
Falcor allows developers to pretend that the object graph their applications needs — in the presentation, this is mostly a list of movies and TV shows — is not floating off in “the cloud” somewhere, but instead exists right there on the machine you’re working on. The problem is that you’re pretending, while things like network latency are real. But we’re getting ahead of ourselves.
Husain’s a good presenter. He goes into detail about how Falcor uses JSON Graph which — and hopefully this is not a surprise — makes JSON act like a graph. Like a lot of apps today, Netflix builds a whole graph of the world around the currently logged-in user, but this introduces a data representation problem, because JSON’s a hieararchical format. JSON Graph solves this by giving its “nodes” (or node-equivalent objects) ids, and uses references to those ids rather than duplicating the objects within the JSON hierarchy. References are like symlinks, from Unix-like operating systems, which solve the same problem of turning a hierarchical data structure into a directed acyclic graph. Values in the graph are cached, and network requests are optimized through batching and de-duping.
I admire the implementation’s ingenuity, but the fundamental idea is kind of a hard sell for me. I spent years as a Rails developer, and Rails’s ActiveRecord tries to do the same thing, except for SQL databases, not “the cloud.” Every developer who’s used Rails has found that abstracting away the datastore allows them to build stuff quickly, which often leads to inflated expectations. Because the complexity is merely obscured, not reduced. Eventually, the romance fades.
Developers are still in that honeymoon phase right now with things like Falcor and Relay. I can’t blame them for that. A similar phase lasted for years with me and ActiveRecord. However, using Joel Spolsky’s term, ActiveRecord’s a leaky abstraction, a social fiction which tries, and ultimately fails, to conceal how the underlying “machinery” works. Sooner or later, you run into problems which are unsolvable unless you know exactly how the underlying “machinery” works. Back in 2002, Spolsky wrote:
Even assembly programmers are supposed to be allowed to pretend that they have a big flat address space, but virtual memory means it’s really just an abstraction, which leaks when there’s a page fault and certain memory fetches take way more nanoseconds than other memory fetches.
Leaky abstractions are a fundamental problem in programming. They can trip you up whether you’re building web apps or hacking assembly.
Fallacies Of Distributed Computing
Libraries for distributed computing are particularly susceptible to leaky abstractions, especially when making the network invisible is a design goal. Because you really can’t make the network go away. The idea that you can is based on fallacies of distributed computing, such as the network is reliable or latency is zero. Belief in these fallacies is natural, which is why engineers at Sun Microsystems, who designed and developed the Java programming platform, were warning developers about them twenty years ago.
I think Falcor will probably lead to some productivity boosts for people who use it, but I also think that if it’s hard to wrap a database without creating a leaky abstraction, it’s probably a lot harder to wrap a database and “the cloud” up into one thing without creating a leaky abstraction too. Remember, Falcor’s not just proposing to turn a datastore into something you don’t need to think about; it’s also trying to create a situation where you won’t need to think about the network between you and the datastore either. That’s a lot for any single abstraction to contain.
Fight The Pedants!
I want to make it clear that I don’t hate Falcor. Last year, when Facebook released Relay, they published a wildly inaccurate “takedown” of REST, we published our own counter-takedown. We thought we were taking down a bully, but there was also a flood of comments from Hacker News suggesting that we were the bullies. One commenter praised Facebook for their courage in standing up to “the HTTP pedants.” As surreal as it was to see people imply that our tiny company was bullying Facebook, which reported $17.93B in revenue last year, our passion for the subject matter obscured our arguments.
So, I’ll be clear.
Husain is a smart developer trying to solve hard problems in innovative ways.
He makes some good points about the
GET verbs in HTTP
being analogous to getter and setter methods in object-oriented languages
(in fact, that may be more significant than he realizes,
but that’s another blog post).
His criticisms of REST are more coherent and credible than Facebook’s screed,
although that still doesn’t mean we agree with them.
What Might Have Been?
All that said, Falcor (and Relay) are attempting to abstract away both the network and the data store, when no one has fully succeeded in doing either. It’s ambitious, to say the least, and I wonder what all that ingenuity and effort would have yielded if it had been applied in the service of the world’s most successful (and, by design, extensible) application protocol, instead of trying to replace it.