Skip to content

Instantly share code, notes, and snippets.

@pacovell
Forked from indexzero/some-resource.js
Created August 26, 2011 20:28
Show Gist options
  • Save pacovell/1174359 to your computer and use it in GitHub Desktop.
Save pacovell/1174359 to your computer and use it in GitHub Desktop.
An example of a possible "resource" API in node.js
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);
});
@indexzero
Copy link

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