-
-
Save benmann/babd5f2d35bd76e0213c to your computer and use it in GitHub Desktop.
// 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; |
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 $atom
s 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.
@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?