Skip to content

Commit

Permalink
[misc] Adde .json view to docs. Updated Docs. Bumped version.
Browse files Browse the repository at this point in the history
  • Loading branch information
Marak committed Feb 2, 2011
1 parent 8351d4a commit 128bfc8
Show file tree
Hide file tree
Showing 6 changed files with 99 additions and 100 deletions.
32 changes: 28 additions & 4 deletions ReadMe.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# warning - library is under active dev. docs and blog are currently out of sync, will be updating soon.

# webservice.js - turn node.js modules into web-services
#### v0.4.8
webservice.js is a somewhat opinionated node.js library that allows developers to easily create RESTFul web-services based on the exports of node.js modules. Having to deal with both implementing and consuming 100s of web-services over the past ten years, I've grown bitter of web-services with arbitrary restrictions, poor documentation, and piles of boiler-plate code. webservice.js tries to solve these problems by implementing RESTFul principals in a much more relaxed fashion.
#### v0.4.9
webservice.js is a somewhat opinionated node.js library that allows developers to easily create RESTFul web-services based on the exports of node.js modules. Having to deal with both implementing and consuming 100s of web-services over the past ten years, I've grown bitter of web-services with arbitrary restrictions, poor documentation, and piles of boiler-plate code. webservice.js tries to solve these problems by implementing RESTFul principals in a much more relaxed fashion.

webservice.js also plays very nice with node's httpServer and other middleware frameworks ( such as Connect ).

Expand Down Expand Up @@ -68,12 +68,36 @@ Regular JavaScript methods are automatically transformed into API methods for yo



### The demo module
### demoModule.js

this.title = "Welcome to your webservice!";
this.name = "demo api module";
this.version = "0.1.0";
this.endpoint = "http://localhost:8080";

exports.echo = function(options, callback){
callback(null, options.msg);
};
exports.echo.description = "this is the echo method, it echos back your msg";
exports.echo.schema = {
msg: {
type: 'string',
optional: false
}
};

exports.ping = function(options, callback){
setTimeout(function(){
callback(null, 'pong');
}, 2000);
}
exports.ping.description = "this is the ping method, it pongs back after a 2 second delay";

#### demoModule.js

## Usage

Once you have started up your web-service, visit http://localhost:8080/docs

## tests

tests are good. npm install vows, then run:
Expand Down
44 changes: 0 additions & 44 deletions examples/demoModule.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,53 +16,9 @@ exports.echo.schema = {
};

exports.ping = function(options, callback){

setTimeout(function(){
callback(null, 'pong');
}, 2000);

}
exports.ping.description = "this is the ping method, it pongs back after a 2 second delay";


exports.user = function(options, callback){


switch(this.request.method){

case 'GET':
if(options.id){
return callback(null, 'got the user with id ' + options.id);
}
else{
return callback(null, 'got all users');
}
break;

case 'POST':
return callback(null, 'created a user with id ' + options.id + ' and arguments: ' + JSON.stringify(options));
break;

case 'UPDATE':
return callback(null, 'updated the user with id' + options.id);
break;

case 'DELETE':
return callback(null, 'deleted the user with id' + options.id);
break;


}

};
exports.user.restful = true;
exports.user.schema = {
"name":{"type":"string"},
"nickname":{"type":"string","optional":true},
"url":{"type":"string","format":"url","optional":true},
"email":{
"type":"string",
"optional":false
}
};
exports.user.description = "user is a restful resource. its actions will depend on the type of http verb you specify.";
47 changes: 35 additions & 12 deletions lib/createRouter.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ var ws = require('./webservice'),

var createRouter = exports.createRouter = function createRouter( module, options ){


var template = fs.readFileSync(__dirname + '/views/home.html'),
routes = _createMetaRoutes( module );

Expand All @@ -31,21 +30,25 @@ var createRouter = exports.createRouter = function createRouter( module, options
res.send(200, {'Content-Type': 'text/html'}, ws.view.renderRoutes('html', '', routes, template.toString()));
});

// returns the docs of the API
map.get('/docs.json').bind(function (res) {
res.send(200, {'Content-Type': 'text/html'}, ws.view.renderRoutes('html', '', routes, JSON.stringify(routes)));
});

// returns the version of the API
map.get('/version').bind(function (res) {
res.send(200, {'Content-Type': 'text/html'}, { version: journey.version.join('.') });
});

// extend the Journey router with our generated routes based on the module
_extendRouter(map, module);
_extendRouter(map, module, options);

}, { strict: false });

return router;

}

function _extendRouter( map, module ){
function _extendRouter( map, module, options ){

// iterate through each top-level method in the module and create a route for it in journey
for(var method in module){
Expand All @@ -56,44 +59,64 @@ function _extendRouter( map, module ){

var regex = new RegExp('\/' + method + '\/(.*?)'),
regexfix = new RegExp('\/' + method),
journeyHandler = _createJourneyHandler(module, method);
journeyHandler = _createJourneyHandler(module, method, options);


// hard-coded for one additional layer of restful methods
for(var p in module[method]){
if(typeof module[method][p] == "function"){
var a = new RegExp('\/' + method + '\/([\w|\-]+)');
map.route(a).bind(journeyHandler);
}
}


// we should only have one handler being bound, this is a regex bug
map.route(regex).bind(journeyHandler);
map.route(regexfix).bind(journeyHandler);

}
}

function _createJourneyHandler(module, method){
function _createJourneyHandler(module, method, options){

var handler = function (res, resource, id, params) {

var args = [], options = {}, self = this;
var args = [], method_options = {}, self = this;

console.log(resource);
console.log(id);
console.log(params);

if(typeof resource != 'object'){
options.id = resource;
method_options.id = resource;
}

for(var p in resource){
if(resource[p].length){
options[p] = resource[p];
method_options[p] = resource[p];
}
}

try{
var posted = JSON.parse(this.request.body);
for(var p in posted){
if(posted[p].length){
options[p] = posted[p];
method_options[p] = posted[p];
}
}
}
catch(err){
}

// bind all createHandler options to each argument
for(var p in options){
method_options[p] = options[p];
}

module[method].request = this.request;
module[method].res = res;
args.push(options);
args.push(method_options);

var callback = _createModuleCallback(self, res);

Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "webservice",
"description": "turns modules into RESTFul web-services",
"version": "0.4.8",
"version": "0.4.9",
"author": "Marak Squires <marak.squires@gmail.com>",
"repository": {
"type": "git",
Expand Down
9 changes: 2 additions & 7 deletions server.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,5 @@
var webservice = require('./lib/webservice'),
demoModule = require('./examples/demoModule'),
fs = require('fs'),
sys = require('sys'),
assert = require('assert');

demoModule = require('./examples/demoModule');

webservice.createServer(demoModule).listen(8080);

console.log(' > json webservice started on port 8080');
console.log(' > json webservice started on port 8080');
65 changes: 33 additions & 32 deletions tests/test-webservice.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,22 +59,6 @@ vows.describe('webservice/').addBatch({
assert.equal(body, 'ohai');
}
},
"a GET request against /echo?msg=ohai": {
topic: function() {
var options = {
uri: host + ':' + port + '/echo?msg=ohai',
method: 'GET'
};

request(options, this.callback)
},
"should respond with 200": function (error, response, body) {
assert.equal(response.statusCode, 200);
},
"should respond with ohai": function (error, response, body) {
assert.equal(body, 'ohai');
}
},
"a GET request against /echo?msg=1": {
topic: function() {
var options = {
Expand All @@ -91,21 +75,6 @@ vows.describe('webservice/').addBatch({
assert.equal(body, '1');
}
},
"a GET request against /aJSONPService?callback=jsonp1295581437634": {
topic: function() {
var options = {
uri: host + ':' + port + '/aJSONPService',
method: 'POST',
body: JSON.stringify({msg:"ohai"})
}
},
"should respond with 200": function (error, response, body) {
assert.equal(response.statusCode, 200);
},
"should respond with ohai": function (error, response, body) {
assert.equal(body, '"ohai"');
}
},
"a POST request to /echo with JSON": {
topic: function() {
var options = {
Expand Down Expand Up @@ -171,8 +140,40 @@ vows.describe('webservice/').addBatch({
"should respond with pong": function (error, response, body) {
assert.equal(body, 'pong');
}
},
"a GET request against /docs": {
topic: function() {
var options = {
uri: host + ':' + port + '/docs',
method: 'GET'
};

request(options, this.callback)
},
"should respond with 200": function (error, response, body) {
assert.equal(response.statusCode, 200);
},
"should return html view representing web-service": function (error, response, body) {
assert.equal(body[0], '<');
}
},
"a GET request against /docs.json": {
topic: function() {
var options = {
uri: host + ':' + port + '/docs.json',
method: 'GET'
};

request(options, this.callback)
},
"should respond with 200": function (error, response, body) {
assert.equal(response.statusCode, 200);
},
"should return JSON representing web-service": function (error, response, body) {
var json = JSON.parse(body);
assert.isObject(json);
}
}

}
}).addBatch({
"when the tests are over": {
Expand Down

0 comments on commit 128bfc8

Please sign in to comment.