columbo
v3.0.1
Published
Framework agnostic, automagical RESTful resource discoverer
Downloads
34
Readme
Columbo
RIMMER: You can scoff, Lister. That's nothing new. They laughed at Galileo. They laughed at Edison. They laughed at Columbo.
LISTER: Who's Columbo?
RIMMER: The man with the dirty mac who discovered America.Red Dwarf Season 1, Episode 4
Discovers REST resources in js files named by convention. Is it a good idea? I don't know. Either way, it makes setting up a REST interface pretty easy.
Usage
URLs
Put your resource classes in a folder (the default is name is resources
). Follow the convention:
Library.js
LibraryBook.js
or
LibraryResource.js
LibraryBookResource.js
This will generate resources for the following URLs:
/libraries
/libraries/{libraryId}/books
/libraries/{libraryId}/books/{bookId}
### Methods
HTTP Methods are determined by the methods exposed on your resource classes. An OPTIONS resource is generated dynamically.
Your methods should accept whatever arguments your web framework requires.
LibraryBook = function() {
};
LibraryBook.prototype.retrieve = function() {
// generates GET with a URL parameter named 'id'
};
LibraryBook.prototype.retrieveAll = function() {
// generates GET with no URL parameter
};
LibraryBook.prototype.retrieveOne = function() {
// generates GET with no URL parameter (intended for singletons, do no use with retrieve and retrieveAll)
};
LibraryBook.prototype.create = function() {
// generates POST
};
LibraryBook.prototype.update = function() {
// generates PUT
};
LibraryBook.prototype.patch = function() {
// generates PATCH
};
LibraryBook.prototype.remove = function() {
// generates DELETE
};
API
var Columbo = require("columbo");
// all options are, well, optional
var columbo = new Columbo({
// The path to the resources directory
resourceDirectory: "./resources",
// All files in `resourceDirectory` will be `require`d - pass a function here
// to override how the resources are created. `resource` will be whatever is
// returned from `require` and `name` is the camelised name of the file
resourceCreator: function(resource, name) {
return new resource()
},
// This will be called for every resource found - if you need to edit the resource
// definition, do it here then pass it to the callback
preProcessor: function(resource, callback) {
callback(undefined, resource)
},
// In order to support :id or {id} form url arguments, pass a function here
// that will return arguments in the format you desire.
idFormatter: function(id) {
return "{" + id + "}";
},
// Responder for OPTIONS requests - the first argument will be an array of
// strings corresponding to HTTP verbs, subsequent arguments are supplied by
// your web framework of choice.
optionsSender: function(opts, request) {
request.reply(opts);
},
// Optionally pass in a logger (e.g. Winston) - defaults to console.
logger: {}
});
// Discover resources
var resources = columbo.discover();
Above resources
will be an array:
[
{
method: String, // e.g. GET
path: String, // e.g. /foo
handler: Function // a bound function - the method on the resource class
}, ...
]
You can then use it with Hapi
var columbo = new Columbo();
var server = new Hapi.Server();
server.addConnection({port: 3000});
columbo.discover(function(error, routes) {
server.route(routes);
server.start();
})
Or with Express:
var app = express();
...
var columbo = new Columbo({
idFormatter: function(id) {
return ":" + id;
},
optionsSender: function(options, request, response) {
response.json(options);
}
});
columbo.discover(function(error, routes) {
routes.forEach(function(resource) {
app[resource.method.toLowerCase()](resource.path, resource.handler);
});
})
Etc, etc.
Todo
- Framework agnostic argument validation
- OPTIONS is a little half baked