Skip to content

Commit

Permalink
Merge branch 'jsonrpc'
Browse files Browse the repository at this point in the history
  • Loading branch information
tj committed Aug 6, 2010
2 parents 8a2d232 + f6e416b commit 28433fb
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 62 deletions.
22 changes: 7 additions & 15 deletions docs/jsonrpc.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,33 +3,25 @@
The _jsonrpc_ middleware provides JSON-RPC 2.0 support. Below is an example exposing the _add_ and _sub_ methods:

var math = {
add: function(a, b){
try {
this(null, a + b);
} catch (err) {
this(err);
}
add: function(a, b, fn){
fn(null, a + b);
},
sub: function(a, b){
try {
this(null, a - b);
} catch (err) {
this(err);
}
sub: function(a, b, fn){
fn(null, a - b);
}
};

var date = {
time: function(){
this(null, new Date().toUTCString());
time: function(fn){
fn(null, new Date().toUTCString());
}
};

connect.createServer(
connect.jsonrpc(math, date)
);

The value of _this_ becomes the async callback function. When you wish to pass an exception simply invoke `this(err)`, or pass the error code `this(jsonrpc.INVALID_PARAMS)`. Other `this(null, result)` will respond with the given results.
When you wish to pass an exception simply invoke `fn(err)`, or pass the error code `fn(jsonrpc.INVALID_PARAMS)`. Otherwise `fn(null, result)` will respond with the given results.

### Features

Expand Down
18 changes: 5 additions & 13 deletions examples/jsonrpc/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,27 +9,19 @@ var connect = require('../../lib/connect');
// curl -H "Content-Type: application/json" -d '{ "jsonrpc": "2.0", "method": "add", "params": { "b": 1, "a": 2 }, "id":2 }' http://localhost:3000

var math = {
add: function(a, b){
try {
this(null, a + b);
} catch (err) {
this(err);
}
add: function(a, b, fn){
fn(null, a + b);
},
sub: function(a, b){
try {
this(null, a - b);
} catch (err) {
this(err);
}
fn(null, a - b);
}
};

// curl -H "Content-Type: application/json" -d '{ "jsonrpc": "2.0", "method": "time", "id":2 }' http://localhost:3000

var date = {
time: function(){
this(null, new Date().toUTCString());
time: function(fn){
fn(null, new Date().toUTCString());
}
};

Expand Down
15 changes: 13 additions & 2 deletions lib/connect/middleware/jsonrpc.js
Original file line number Diff line number Diff line change
Expand Up @@ -97,19 +97,22 @@ function jsonrpc(services) {
var method = services[rpc.method];
if (typeof method === 'function') {
var params = [];
// Unnamed params
if (Array.isArray(rpc.params)) {
params = rpc.params;
// Named params
} else if (typeof rpc.params === 'object') {
var names = method.toString().match(/\((.*?)\)/)[1].match(/[\w]+/g);
if (names) {
for (var i = 0, len = names.length; i < len; ++i) {
for (var i = 0, len = names.length - 1; i < len; ++i) {
params.push(rpc.params[names[i]]);
}
} else {
// Function does not have named parameters
return respond({ error: { code: INVALID_PARAMS, message: 'This service does not support named parameters.' }});
}
}
// Reply with the given err and result
function reply(err, result){
if (err) {
if (typeof err === 'number') {
Expand All @@ -132,7 +135,15 @@ function jsonrpc(services) {
});
}
}
method.apply(reply, params);
// Push reply function as the last argument
params.push(reply);

// Invoke the method
try {
method.apply(this, params);
} catch (err) {
reply(err);
}
} else {
respond({ error: { code: METHOD_NOT_FOUND }});
}
Expand Down
52 changes: 20 additions & 32 deletions test/jsonrpc.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ var connect = require('connect'),
helpers = require('./helpers'),
assert = require('assert'),
http = require('http'),
jsonrpc = require('connect/middleware/jsonrpc')
jsonrpc = require('connect/middleware/jsonrpc');

function run(procedures){
var server = helpers.run(
Expand Down Expand Up @@ -74,17 +74,18 @@ module.exports = {

'test passing method exceptions': function(){
var server = run({
add: function(a, b){
if (arguments.length === 2) {
add: function(a, b, fn){
if (arguments.length === 3) {
if (typeof a === 'number' && typeof b === 'number') {
this(null, a + b);
fn(null, a + b);
} else {
var err = new Error('Arguments must be numeric.');
err.code = jsonrpc.INVALID_PARAMS;
this(err);
fn(err);
}
} else {
this(jsonrpc.INVALID_PARAMS);
fn = arguments[arguments.length - 1];
fn(jsonrpc.INVALID_PARAMS);
}
}
});
Expand Down Expand Up @@ -125,8 +126,8 @@ module.exports = {

'test methode call': function(){
var server = run({
add: function(a, b){
this(null, a + b);
add: function(a, b, fn){
fn(null, a + b);
}
});
server.call({
Expand All @@ -142,11 +143,13 @@ module.exports = {
'test variable arguments': function(){
var server = run({
add: function(){
var sum = 0;
for (var i = 0, len = arguments.length; i < len; ++i) {
var sum = 0,
fn = arguments[arguments.length - 1],
len = arguments.length - 1;
for (var i = 0; i < len; ++i) {
sum += arguments[i];
}
this(null, sum);
fn(null, sum);
}
});
server.call({
Expand All @@ -161,14 +164,10 @@ module.exports = {

'test named params': function(){
var server = run({
delay: function(ms, msg, unused){
var respond = this;
delay: function(ms, msg, unused, fn){
setTimeout(function(){
respond(null, msg);
fn(null, msg);
}, ms);
},
invalid: function( ){
this(null, 'shouldnt reach here because I dont have named param support :)');
}
});

Expand All @@ -180,26 +179,15 @@ module.exports = {
}, function(res, body){
assert.eql({ id: 1, result: 'Whoop!', jsonrpc: '2.0' }, body);
});

server.call({
jsonrpc: '2.0',
method: 'invalid',
params: { msg: 'Whoop!', ms: 50 },
id: 2
}, function(res, body){
assert.eql({ id: 2, error:
{ code: jsonrpc.INVALID_PARAMS, message: 'This service does not support named parameters.' },
jsonrpc: '2.0' }, body);
});
},

'test batch calls': function(){
var server = run({
multiply: function(a, b){
this(null, a * b);
multiply: function(a, b, fn){
fn(null, a * b);
},
sub: function(a, b){
this(null, a - b);
sub: function(a, b, fn){
fn(null, a - b);
}
});
server.call([{
Expand Down

0 comments on commit 28433fb

Please sign in to comment.