-
Notifications
You must be signed in to change notification settings - Fork 10
Home
###An easy to use middle tier framework for javascript.
peasy-js is a middle tier framework that offers an extremely easy to use and flexible rules engine and was designed to address common challenges such as concurrency handling, transactional support, fault tolerance, threading, scalability, async and multiple client support, and easy testability. It was designed to save you from countless hours of design and development time.
Here are the concerns that peasy was designed to address:
- Easy to use validation/business rules engine
- Code sharing
- Thread safety
- Scalability
- Concurrency
- Swappable data proxies
- Async support
- Multiple client support
- Multiple deployment scenario support
- Transactional support and fault tolerance
- Easy testability
- AMD, Browser, and CommonJS support
This sample requires nodejs.
Start by creating a directory to house your code.
From a command line within your new directory, install peasy-js via npm install peasy-js
.
Next create a data proxy by creating a file (personDataProxy.js) with the following content:
// personDataProxy.js
var PersonDataProxy = function() {
this.data = [];
this.getById = function(id, done) {
var person = this.findBy(id);
done(person);
};
this.getAll = function(done) {
done(this.data);
};
this.insert = function(data, done) {
data.id = this.data.length + 1;
this.data.push(data);
done(data);
};
this.update = function(data, done) {
var person = this.findBy(data.id);
person.name = data.name;
done(person);
};
this.delete = function(id, done) {
var person = this.findBy(id);
var index = this.data.indexOf(person);
this.data.splice(index, 1);
done();
};
this.findBy = function(id) {
var person = this.data.filter((function(p) {
return p.id === id;
}))[0];
return person;
}
};
module.exports = PersonDataProxy;
Then, create a service class file (personService.js), which exposes CRUD commands responsible for subjecting data proxy invocations to business rules before execution:
// personService.js
var BusinessService = require('peasy-js').BusinessService;
var PersonService = BusinessService.extend().service;
module.exports = PersonService;
Now let's consume our PersonService by creating a file (example.js) with the following contents:
// example.js
var peasy = require('peasy-js');
var PersonDataProxy = require('./personDataProxy');
var PersonService = require('./personService');
var personService = new PersonService(new PersonDataProxy());
var command = personService.insertCommand({name: "James Morrison"});
command.execute(function(result) {
if (result.success) {
console.log(result.value); // prints the inserted object with the assigned id
}
});
Testing it out from command line: node example.js
Let's create a business rule file (personNameRule.js) whose execution must be successful before the call to inject dataproxy.insert() function is invoked.
// personNameRule.js
var Rule = require('peasy-js').Rule;
var PersonNameRule = Rule.extend({
association: "name",
params: ['name'],
onValidate: function(done) {
if (this.name === "Fred Jones") {
this.__invalidate("Name cannot be Fred Jones");
}
done();
}
});
module.exports = PersonNameRule;
And wire it up in our PersonService to ensure that it gets fired before inserts:
// personService.js
var BusinessService = require('peasy-js').BusinessService;
var PersonNameRule = require('./personNameRule');
var PersonService = BusinessService.extend({
functions: [{
'__getRulesForInsert': function(person, context, done) {
done([ new PersonNameRule(person.name) ]);
}
}]
}).service;
module.exports = PersonService;
Testing it out ...
// example.js
var peasy = require('peasy-js');
var PersonDataProxy = require('./personDataProxy');
var PersonService = require('./personService');
var dataProxy = new PersonDataProxy();
var personService = new PersonService(dataProxy);
var command = personService.insertCommand({name: "Fred Jones"});
command.execute(function(result) {
if (result.success) {
console.log(result.value);
} else {
console.log(result.errors); // prints the errors as a result of the failed PersonNameRule
}
});
Testing it out from command line: node example.js
Let's create one more rule (validCityRule.js), just for fun:
// validCityRule.js
var Rule = require('peasy-js').Rule;
var ValidCityRule = Rule.extend({
association: "city",
params: ['city'],
onValidate: function(done) {
if (this.city === "Nowhere") {
this.__invalidate("Nowhere is not a city");
}
done();
}
});
module.exports = ValidCityRule;
We'll associate this one with inserts too:
// personService.js
var BusinessService = require('peasy-js').BusinessService;
var PersonNameRule = require('./personNameRule');
var ValidCityRule = require('./validCityRule');
var PersonService = BusinessService.extend({
functions: [{
'__getRulesForInsert': function(person, context, done) {
done([
new PersonNameRule(person.name),
new ValidCityRule(person.city)
]);
}
}]
}).service;
module.exports = PersonService;
And test it out ...
// example.js
var peasy = require('peasy-js');
var PersonDataProxy = require('./personDataProxy');
var PersonService = require('./personService');
var dataProxy = new PersonDataProxy();
var personService = new PersonService(dataProxy);
var command = personService.insertCommand({name: "Fred Jones", city: "Nowhere"});
command.execute(function(result) {
if (result.success) {
console.log(result.value);
} else {
console.log(result.errors); // prints the errors as a result of the failed PersonNameRule and ValidCityRule rules
}
});
Testing it out from command line: node example.js
Finally, let's pass in valid data and watch it be a success
// example.js
var peasy = require('peasy-js');
var PersonDataProxy = require('./personDataProxy');
var PersonService = require('./personService');
var dataProxy = new PersonDataProxy();
var personService = new PersonService(dataProxy);
var command = personService.insertCommand({name: "Freida Jones", city: "Madison"});
command.execute(function(result) {
if (result.success) {
console.log(result.value); // prints the inserted object with the assigned id
} else {
console.log(result.errors);
}
});
Testing it out from command line: node example.js