-
-
Save pacovell/1174359 to your computer and use it in GitHub Desktop.
An example of a possible "resource" API in node.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var util = require('util'), | |
resourceLib = require('our-new-resource-lib'); | |
var SomeResource = function (options) { | |
resourceLib.Resource.call(this, options); | |
// | |
// Setup any other application specific state. | |
// | |
// Define actions (these default actions would likely be in the parent resource; shown here as an example) | |
var actions = [ | |
{ name: 'index', method: 'get', scope: 'collection' }, | |
{ name: 'show', method: 'get', scope: 'element' }, | |
{ name: 'edit', method: 'get', scope: 'element' }, | |
{ name: 'update', method: 'put', scope: 'element' }, | |
{ name: 'new', method: 'get', scope: 'collection' }, | |
{ name: 'create', method: 'post', scope: 'collection' }, | |
{ name: 'destroy', method: 'delete', scope: 'element' }, | |
]; | |
this.addActions(actions); | |
// | |
// Require authentication on all actions, authorize on edit, update, delete | |
// Can also be added later, as below | |
// | |
this.before('all', 'authenticate'); | |
this.before(['edit', 'update', 'delete'], 'authorize'); | |
// | |
// Around filter structured like this | |
/* | |
function log(original, req, res, next) { | |
// before | |
original(req, res, function() { | |
// after | |
next(); | |
}); | |
}; | |
*/ | |
this.around('all', 'log'); | |
// | |
// Setup this resource to use CouchDB. | |
// | |
// PAC: not sure what you're going to do based on this? Will this store or set up a database object? | |
// this.set('db', couch); | |
}; | |
util.inherits(SomeResource, resourceLib.Resource); | |
// | |
// Actions support a series of "filters", executed in the order added | |
// Can also be added in initialization | |
// | |
SomeResource.before(['edit', 'update', 'delete'], 'authorize'); // call by name on this | |
SomeResource.before(['edit', 'update', 'delete'], authorize); // or use a function | |
SomeResource.before('index', function(req, res, next) { | |
// Also can be declared 'inline' so you can organize functional groups | |
db.spaceMonkeys.findOne({_id: req.query.spaceMonkeyId}, this.setCallback('spaceMonkey')); | |
// If we are very clever, next will execute after all the this.setCallback() are completed, | |
// and we won't need a separate async library here. | |
next(); | |
}); | |
SomeResource.prototype.index = function(req, res, next) { | |
// TODO: need a way to cleanly render different results for different request types -- eg, | |
// a status message for JSON/JS, or a page render for a web client. | |
this.set('monkeyLevel', 5); | |
// Render will have any 'set' values passed in as locals that can be used in view rendering | |
this.render(next); | |
}; | |
SomeResource.after('index', function(req, res, next) { | |
this.spaceMonkey.save(next); | |
}); |
And, I'm going to replace mongoose with a very thin layer on mongodb native
I think events is the right way to integrate with the routing layer. In this way you can easily decouple them. Also, if you're dropping mongoose we should talk about how we could pull that into a resourcer engine
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Yes, except I'm interested in having the routing implementation just emit an event for the right resource and then consider it handled. Is this feasible?