Optimising a node.js falcor router between a traditional REST API data source and a Falcor client

254 views Asked by At

I have a traditional REST API, that returns data like so:

User list - GET /users.json

users: [
    {id: 0, name: "John Smith"},
    ...
]

Users by Id - GET /users/0.json

user: {
    id: 0,
    name: "John Smith"
}

As you can see, if you first request the data from the list (/users.json), and then click on a user, even though the information was present in the first list, it is re-requested from the user by id request.

In Falcor, this would be solved by having a list of references in the first call.

My question is, if I am writing a Falcor router to act as a middleman, how do I optimise such a scenario? Currently, the router has to request the full user list, and then throw out the information and return a list of references based on the ids to the client. This still saves bandwidth on the client side but is suboptimal between the Falcor router and its datasource (REST API).

1

There are 1 answers

4
Hugo Wood On

It is possible to workaround this situation, but first, I would like to explain why you are seeing this mismatch. It is because Falcor respect REST principles, but your API does not. REST states that data coming from the API should be cacheable. It cannot be cacheable if it resides in two places at once. For example, if I were to PUT or PATCH /users/0.json, how can the client know that this operation has an impact on /users.json (a different resource) and invalidate its cache? It cannot. In fully-compliant HTTP REST APIs and Falcor APIs alike, data resides in one place only, and then it can be linked to via refs. For HTTP, refs are URLs, and so a GET call to /users.json should respond with a list of URLs like ["/users/0.json", "/users/1.json"].

That said, it does not mean you are out of luck.

What you probably want on the Falcor side is to have a route like this: users[{integers:indices}][{keys:props}]. In the handler for this route, you can query pathSet.indices and see how much indices were actually requested. If there is only one (or few), forward the request to /users/${indices[i]}.json, otherwise forward it to /users.json.