The Power of Falcor: Part 1

Falcor is a new open source project from the great engineering team at Netflix. The power of Falcor comes from the use of of a new graph object called JSON Graph. JSON Graph is a new structure for delivering the entire graph on an object in a very simplified javascript object. The team at Netflix has provided great documentation and video on the Falcor page that I highly recommend you read.

Initializing the Connection

Before we create a connection to a remote Falcor router lets begin by providing a local cache to the Falcor model so we can understand how data is retrieved.

var ref = falcor.Model.ref;
var model = new falcor.Model({
  cache: {
     users: {
       44: $ref("usersById[44]")
     }
     usersById: {
        44: {
            name: "David"
        }
     }
  }
});

falcor.Model accepts two arguments: cache and source.

source – Requires a HttpDataSource object that provides a connection to our remote server.
cache – This is one of the core components that allows Falcor to deliver small amounts of data. All Falcor models contain a cache which is an empty object by default. However as you can see in the example above we can initialize the model with a cache.

Intro To Cache

When we look at the cache provided when we initialize our Falcor model you will notice the use of ref. Falcor provides us with a helper function to generate references to resources. This allows us to reuse a single resource in multiple locations in the object.

{
   usersById: {
     44: {
        name: "David",
        friends: [
          $ref('usersById[45]')
        ]
     },
     45: {
        name: "John",
        friends: [
          $ref('usersById[44]')
        ]
     },
   }
}

In the example above each user has a list of friends that contains an array of references to other resources in the object. The benefit of this approach is making an update to the name of User 44 all users in our cache who have a reference to User 44 will receive the newly updated name. When updating a resource’s property we don’t need to invalidate a cache and retrieve the latest version from a remote server because our local cache has already been updated. Behind the scenes Falcor updates the local model then dispatches a request to the router to update the properties. No need to return the updated value because our local cache already has the latest version.

There isn’t a lot of magic behind the ref helper function. If we look at the output of the function you will see it just provides us shorthand instead of writing:

{ $type: "ref", value: "usersById[44]" }

Requesting A Single Property

Now that we have a connection established to our Model lets request the location property of User #44.

model
  .getValue("users[44].location")
  .then(function(location) {
    console.log(location);
  });

Behind the scenes Falcor analyzes the cache by first looking at the user object then analyzing if the object contains the key 44 and then proceeds to determine if the object contains the key location when the cache doesn’t contain the requested property it will then proceed to make a request to the Falcor server if you provided a remove server connection.

Requesting Multiple Properties

In the previous example we learned how to request a single property on a single record, but in the real world we typically want to request multiple properties from multiple resources.The real power of JSON Graph begins to reveal itself when making a request for multiple properties on multiple resources.

model
   .get("users["44..45"]["location","name"]")
   .then(function(response) {
      console.log(JSON.stringify(response))
   });

The first thing you probably noticed is this time we are using .get instead of .getValue. The reason for the change is get will only return a single property and getValue returns a JSON Graph object.

The next new thing you probably noticed is the syntax for retrieving multiple objects. In JSON Graph we are asking the model to return only the location and name for users[44] & users[45]. JSON Graph allows us to use keys that are arrays to access the graph object so we can easily retrieve multiple resources and specific properties on those resources. Below is a slightly different syntax that produces the same path request as above.

model
   .get(["users", {from: 44, to: 45}, ["location","name"])
   .then(function(response) {
      console.log(JSON.stringify(response))
   });

There is no difference between the two request examples other than syntax used. Behind the scenes Falcor uses path optimization to convert ["users", {from: 44, to: 45}, ["location","name"] => users["44..45"].["location","name"]

Freebies

Everyone loves freebies so here is the link to my very simple and basic Node HAPI server with a Mocha test suite hapi-falcor-playground.

Preview of Part 2

In the next part of this series we will discuss getting started with Falcor router, exploring the request/response payloads, and discovering how Falcor routes allow us to use multiple microservices to return data.