Skip to content

Instantly share code, notes, and snippets.

@benmann
Last active December 31, 2015 14:52
Show Gist options
  • Save benmann/babd5f2d35bd76e0213c to your computer and use it in GitHub Desktop.
Save benmann/babd5f2d35bd76e0213c to your computer and use it in GitHub Desktop.
Wrapping cookiejar DB requests in falcor router
// Client side JS looks like this
model.get("packagesByName.jquery.url").then(function(response) {
// returns: git://github.com/jquery/jquery.git
document.write(response.json.packagesByName.jquery.url);
});
// model looks liek this
model = {
packagesByName:
{ jquery:
{ created_at: '2015-12-29 07:08:36 +0100',
hits: 14384544,
id: 'Vk69zPIGziUx',
isPublic: true,
name: 'jquery',
type: 'package',
url: 'git://github.com/jquery/jquery.git' },
jQuery:
{ created_at: '2015-12-24 17:03:09 +0100',
hits: 47370,
id: '4J_wSnMIbr8x',
isPublic: true,
name: 'jQuery',
type: 'package',
url: 'git://github.com/jquery/jquery.git' },
...
var Falcor = require('falcor-express'),
Router = require('falcor-router'),
bodyParser = require('body-parser'),
config = require('../config/config'),
Package = require('../models/package.js'),
elastic = require('../config/elasticClient'),
rethink = require('../api/rethinkDB'),
isValidURL = require('../helper/validURL'),
isValidName = require('../helper/validName');
var router = Router.createClass([
{
// Get amount of packages
// TODO: fetches from Rethink, should be elastic?
route: 'packages.length',
get: function(req) {
return Package.count().execute().then(function(total) {
return { path: ["packages", "length"], value: total };
});
}
},
{
// Get package properties by name
route: 'packagesByName[{keys:name}]["name","url","owner","description","keywords","created_at","hits","stars","isPublic"]',
get: function(req) {
var packProp = req[2][0],
packName = req.name[0];
return elastic.search({
index: 'packages',
size: config.defaultSize,
body: {
query: {
"multi_match" : {
"query": packName,
"type": "best_fields",
"fields": ["new_val.name", "new_val.description", "new_val.keywords", "new_val.owner"],
"minimum_should_match": "25%",
"fuzziness" : 2,
}
}
}
}).then(function(searchresult) {
var model = {packagesByName:{}};
searchresult.hits.hits.forEach(function(package) {
var pkgName = package._source.new_val.name,
pkgVals = package._source.new_val;
model.packagesByName[pkgName] = pkgVals;
});
return {path:["packagesByName", packName, packProp], value: model.packagesByName[packName][packProp]};
});
}
}
]);
module.exports = router;
@benmann
Copy link
Author

benmann commented Dec 31, 2015

@sheerun so here's a first implementation! :-]
It allows to fetch the different details of a package with only one route which is pretty neat. Some questions I still need to answer are,
whether this actually laverages caching.. It's not a "Falcor.model" as described in examples but uses falcor-express.. I'm a little confused by that.
Another question is whether we should return all properties (hits, id, name...) as one big chunk when a package is requested by name. This would require returning them as $atom (can't return objects). Need to see the implications that brings along, or do we actually want that?

@benmann
Copy link
Author

benmann commented Dec 31, 2015

A little follow-up: I actually think returning the packages as $atom is right for us, as we can then access all its properties on the client. We also know that our object (the package itself) will not grow much, as we have a set amount of properties (stars, url,...). Would be great if we can decide whether we need only the $atoms returned, the single properties or if we have cases that require us to provide both options.

Here's an example ofwhat I mean by returning a package as a whole $atom:

      { created_at: '2015-12-24 17:03:09 +0100',   
        hits: 47370,   
        id: '4J_wSnMIbr8x',   
        isPublic: true,   
        name: 'jQuery',   
        type: 'package',   
        url: 'git://github.com/jquery/jquery.git' }   

That way we can do the following on the client:
var package = response.json.packagesByName.jquery and access its properties, such as
package.url and so on..

Here's the docs section about atoms:

In addition to making it possible to attach metadata to JSON values, Atoms can be used to get around the restriction against retrieving JSON Objects and Arrays from a Falcor Model.
Let’s say that we have an Array which we are certain will remain small, like a list of video subtitles for example. By boxing the subtitles Array in an Atom, we cause the Falcor model to treat it as a value and return it in its entirety.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment