Permalink
Browse files

Initial commit

  • Loading branch information...
0 parents commit cf40e41468caedd14372bfbbca1fb782e433f96e @tj tj committed Feb 25, 2011
Showing with 318 additions and 0 deletions.
  1. +12 −0 .gitmodules
  2. +2 −0 .npmignore
  3. +5 −0 History.md
  4. +5 −0 Makefile
  5. +105 −0 Readme.md
  6. +85 −0 index.js
  7. +8 −0 package.json
  8. +1 −0 support/connect
  9. +1 −0 support/ejs
  10. +1 −0 support/express
  11. +1 −0 support/expresso
  12. +28 −0 test/fixtures/forum.js
  13. +64 −0 test/resource.test.js
@@ -0,0 +1,12 @@
+[submodule "support/expresso"]
+ path = support/expresso
+ url = git://github.com/visionmedia/expresso.git
+[submodule "support/express"]
+ path = support/express
+ url = git://github.com/visionmedia/express.git
+[submodule "support/ejs"]
+ path = support/ejs
+ url = git://github.com/visionmedia/ejs.git
+[submodule "support/connect"]
+ path = support/connect
+ url = git://github.com/senchalabs/connect.git
@@ -0,0 +1,2 @@
+support
+test
@@ -0,0 +1,5 @@
+
+0.0.1 / 2010-09-06
+==================
+
+ * Initial release
@@ -0,0 +1,5 @@
+
+test:
+ @./support/expresso/bin/expresso
+
+.PHONY: test
105 Readme.md
@@ -0,0 +1,105 @@
+
+# Express Resource
+
+ express-resource provides resourceful routing to express.
+
+## Installation
+
+npm:
+
+ $ npm install express-resource
+
+## Usage
+
+ To get started simply `require('express-resource')`, and this module will monkey-patch the `express.Server`, enabling resourceful routing. A "resource" is simply an object, which defines one of more of the supported "actions" listed below:
+
+ exports.index = function(req, res){
+ res.send('forum index');
+ };
+
+ exports.new = function(req, res){
+ res.send('new forum');
+ };
+
+ exports.create = function(req, res){
+ res.send('create forum');
+ };
+
+ exports.show = function(req, res){
+ res.send('show forum ' + req.params.id);
+ };
+
+ exports.edit = function(req, res){
+ res.send('edit forum ' + req.params.id);
+ };
+
+ exports.update = function(req, res){
+ res.send('update forum ' + req.params.id);
+ };
+
+ exports.destroy = function(req, res){
+ res.send('destroy forum ' + req.params.id);
+ };
+
+The _id_ option can be specified to prevent collisions:
+
+ exports.id = 'uid';
+
+ exports.destroy = function(req, res) {
+ res.send('destroy user ' + req.params.uid);
+ };
+
+The `app.resource()` method will create and return a new `Resource`:
+
+ var express = require('express')
+ , Resource = require('express-resource')
+ , app = express.createServer();
+
+ app.resource('forums', require('./forum'));
+
+Actions are then mapped as follows (by default):
+
+ GET /forums -> index
+ GET /forums/new -> new
+ POST /forums -> create
+ GET /forums/:id -> show
+ GET /forums/:id/edit -> edit
+ PUT /forums/:id -> update
+ DELETE /forums/:id -> destroy
+
+__NOTE:__ this functionality will surely grow with time, and as data store clients evolve we can provide close integration.
+
+## Running Tests
+
+First make sure you have the submodules:
+
+ $ git submodule update --init
+
+Then run the tests:
+
+ $ make test
+
+## License
+
+(The MIT License)
+
+Copyright (c) 2010 TJ Holowaychuk <tj@vision-media.ca>
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+'Software'), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,85 @@
+
+/*!
+ * Express - Resource
+ * Copyright(c) 2010 TJ Holowaychuk <tj@vision-media.ca>
+ * MIT Licensed
+ */
+
+/**
+ * Module dependencies.
+ */
+
+var express = require('express')
+ , Server = express.Server;
+
+/**
+ * Initialize a new `Resource` with the given `name` and `actions`.
+ *
+ * @param {String} name
+ * @param {Object} actions
+ * @param {Server} app
+ * @api private
+ */
+
+var Resource = module.exports = function Resource(name, actions, app) {
+ this.name = name;
+ this.app = app;
+ this.actions = actions
+ this.id = actions.id || 'id';
+ for (var key in actions) {
+ this.defineAction(key, actions[key]);
+ }
+};
+
+/**
+ * Define the given action `name` with a callback `fn()`.
+ *
+ * @param {String} key
+ * @param {Function} fn
+ * @api public
+ */
+
+Resource.prototype.defineAction = function(key, fn){
+ var app = this.app
+ , id = this.id
+ , name = '/' + this.name;
+
+ switch (key) {
+ case 'index':
+ app.get(name, fn);
+ break;
+ case 'new':
+ app.get(name + '/new', fn);
+ break;
+ case 'create':
+ app.post(name, fn);
+ break;
+ case 'show':
+ app.get(name + '/:' + id, fn);
+ break;
+ case 'edit':
+ app.get(name + '/:' + id + '/edit', fn);
+ break;
+ case 'update':
+ app.put(name + '/:' + id, fn);
+ break;
+ case 'destroy':
+ app.del(name + '/:' + id, fn);
+ break;
+ }
+};
+
+/**
+ * Define a resource with the given `name` and `actions`.
+ *
+ * @param {String} name
+ * @param {Object} actions
+ * @return {Resource}
+ * @api public
+ */
+
+Server.prototype.resource = function(name, actions){
+ this.resources = this.resources || {};
+ var res = this.resources[name] = new Resource(name, actions, this);
+ return res;
+};
@@ -0,0 +1,8 @@
+{ "name": "express-resource"
+ , "description": "Resourceful routing for express"
+ , "version": "0.0.1"
+ , "author": "TJ Holowaychuk <tj@vision-media.ca>"
+ , "keywords": ["express", "rest", "resource"]
+ , "main": "index"
+ , "engines": { "node": ">= 0.2.0" }
+}
Submodule connect added at 3a8f69
Submodule ejs added at 76cf94
Submodule express added at 5e0a80
Submodule expresso added at 2c8759
@@ -0,0 +1,28 @@
+
+exports.index = function(req, res){
+ res.send('forum index');
+};
+
+exports.new = function(req, res){
+ res.send('new forum');
+};
+
+exports.create = function(req, res){
+ res.send('create forum');
+};
+
+exports.show = function(req, res){
+ res.send('show forum ' + req.params.id);
+};
+
+exports.edit = function(req, res){
+ res.send('edit forum ' + req.params.id);
+};
+
+exports.update = function(req, res){
+ res.send('update forum ' + req.params.id);
+};
+
+exports.destroy = function(req, res){
+ res.send('destroy forum ' + req.params.id);
+};
@@ -0,0 +1,64 @@
+
+/**
+ * Module dependencies.
+ */
+
+var express = require('express')
+ , Resource = require('../')
+ , assert = require('assert');
+
+module.exports = {
+ 'test app.resource()': function(){
+ var app = express.createServer();
+
+ var ret = app.resource('forums', require('./fixtures/forum'));
+ assert.ok(ret instanceof Resource);
+
+ assert.response(app,
+ { url: '/forums' },
+ { body: 'forum index' });
+
+ assert.response(app,
+ { url: '/forums/new' },
+ { body: 'new forum' });
+
+ assert.response(app,
+ { url: '/forums', method: 'POST' },
+ { body: 'create forum' });
+
+ assert.response(app,
+ { url: '/forums/5' },
+ { body: 'show forum 5' });
+
+ assert.response(app,
+ { url: '/forums/5/edit' },
+ { body: 'edit forum 5' });
+
+ assert.response(app,
+ { url: '/forums/5', method: 'PUT' },
+ { body: 'update forum 5' });
+
+ assert.response(app,
+ { url: '/forums/5', method: 'DELETE' },
+ { body: 'destroy forum 5' });
+ },
+
+ 'test app.resource() id option': function(){
+ var app = express.createServer();
+
+ app.resource('users', {
+ id: 'uid',
+ show: function(req, res){
+ res.send(req.params.uid);
+ }
+ });
+
+ assert.response(app,
+ { url: '/users' },
+ { status: 404 });
+
+ assert.response(app,
+ { url: '/users/10' },
+ { body: '10' });
+ }
+};

0 comments on commit cf40e41

Please sign in to comment.