Open tlvenn opened 9 years ago
Sorry that we have not been responding as quickly as we would like.
You are correct and incorrect at the same time. You are correct that the router should be considered a singleton (in reality its only for performance. You would want a single router so that route parse trees do not have to be constructed per request). To overcome the state of the request vs the singleton router approach is easily overcame via prototype inheritance.
var router = new Router([... routes ...]);
var NetflixRouter = function NetflixRouter(req, res) {
this.req = req;
this.res = res;
}
NetflixRouter.prototype = router;
// ... in the application ...
var NetflixRouter = require('netflix-router');
var falcorMiddleware = require('falcor-express').middleware;
app.get('/models.json', falcorMiddleware(function(req, res) {
return new NetflixRouter(req, res);
});
As far as other frameworks request patterns goes, they may not be reasonable for us. In falcor-router we have routes that can match many sub routes. Of those sub-routes batching (multiple routes processed as a single route) can be determined by the implementor. Here is an example of a heterogeneous list:
// Here is our route
{
route: 'heterList[{ranges:indices}].name',
// for whatever reason indices below 5 are 'videos' and 5 and above are 'series'
// This is a trite example, but hopefully drives some of the complexity considered
// with our current design decisions.
get: function(pathSet) {
var indices = pathSet.indices;
var videos = indices.filter(x => x < 5);
var series = indices.filter(x => x >= 5);
var count = 0;
return Observable.
of(videos, series).
map(function(vidOrSeries) {
return // Array of PathValues or JSONGraph, one for videos, one for series
// thus one route matches two sub routes.
});
}
This one path ['heterList', {to:10}, 'name'] would call two separate paths, collapsing on each onNext. Another point to some of the design decisions were due to each route can fire 0 .. n times with data, of which could match 0 ..n*m more routes.
Hopefully this answer is satisfactory. We are also not opposed to different designs, we simply went with this design as it met Netflix's original router goals.
The more I dig into the router code the more I wonder why the router has not been modeled like an http framework such as Hapi around how it handles requests.
Well given the focus on solving a particular problem for Netflix I understand and it explains the FP approach of the code.
But to future proof so to speak the router and to make sure it can be used by a broader audience, I wonder if it wouldn't be a good idea to do a little refactoring so it becomes more idiomatic and provides extension points so users can easily plug it into their infrastructure.
The problem right now is the Router is expected to be a singleton but in reality it can't really be one because most likely you need it to be stateful and there is not really a well defined object for the request or the response that would allow people to hook into the router request/response lifecycles such as http://www.hapijs.com/api#request-lifecycle
I believe it would help greatly if the router would become a singleton by contract and if we had
FalcorRequest
andFalcorResponse
objects that would help to capture the state in well defined expected objects and provide extension points to hook into the router.