katia-requests
v0.1.2
Published
A NodeJs-Expressjs middleware to easily call server functions from an Angular application.
Downloads
3
Readme
katia-requests
This package is deprecated. Please do not use it.
Node-Expressjs middleware to easily call server functions from an AngularJS application.
In the server, declare one or several modules of functions that should be accessible from the client. In the AngularJS application, call these functions as if they were written in the client scripts. Use katiaRequests service for that.
katia-requests is purposely made to not care about the problems of the communication client-server. Add a function in the proper file on the server and then it is immediatly available on the angular application, without writting any other piece of code.
The client-server communication is based on the json rpc protocol (version 2). The middleware manages the errors whether a bad request is sent : invalid json, invalid request, function not found, invalid number of arguments.
Warning : the server must ever check the arguments passed to the called functions are correct. In the below example, the function add has to check whether a and b are numbers.
Installation
$ npm install katia-requests
Getting started
See the examples at the end.
API
The API consists of three parts : an angular module, an express middleware and one or several node functions modules.
The angular module
The angular module katia-requests must be injected to communicate with the server. Its service katiaRequests contains all the useful methods to make requests to the server. They have the same name that the server functions and the same arguments plus one. This ultimate must be a callback function which is called when the respond is received. The result of the respond is passed as argument.
example
angular
.module('my_app', ['katia-requests'])
.controller('my_controller', ['katiaRequests', function(requests) {
var that = this;
requests.getSomething(function(data) {
that.something = data;
});
//instead of writting : this.something = requests.getSomething();
}]);
The html file must contain this line :
<script type="text/javascript" src="katia-requests.js"></script>
katia-requests.js is generated dynamically from the node functions module(s).
The express middleware
The express middleware generates the angular module from the server functions and processes the requests from this one.
var express = require('express');
var katiaRequests = require('katia-requests');
var app = express();
app.use(katiaRequests('/pathWhereMyServerFunctionsAreDeclared'));
The node functions module(s)
The node functions module(s) contain all the functions which must be available to the client. Each method takes at least two arguments : done and session.
The done([data]) function must be called when the method ends. If a value must be returned, then it is passed as argument. The advantage of the done(data) function instead of a return data is to allow asynchronous programmation such as consulting a database (see example below : Display articles from a database).
The session object contain all the information about the session. It is identical to req.session. You have to write the session argument in the declaration of the function even if you do not use sessions. In this case, it will be equal to undefined.
Options
Options can be passed as second argument in the declaration of the node functions module(s).
var app = require('express')();
var katiaRequests = require('katia-requests');
app.use(katiaRequests('/myFunctions.js', {/*Options*/}));
debugMode
The debugMode displays in the console the request and respond json objects. It also catches the functions' exceptions and sends it in the respond as en error. Use it only during development.
To use the debugMode :
app.use(katiaRequests('/myFunctions.js', {debugMode: true}));
restrict
A middleware can be passed as restrict in the options. It will be called before the node functions module is read. This option is useful to restrict the access of certain functions to certain users.
example
function restrictUser(req, res, next()) {
if (req.session.user)
next();
else res.send('Access denied');
}
app.use(katiaRequests('/myFunctions.js', {restrict: restrictUser}));
Examples
1. A very simple calculator
client
app.js
angular.module('app', ['katia-requests'])
.controller('myController', ['katiaRequests', function(requests) {
var that = this;
this.a = 2;
this.b = 3;
requests.pi(function(data) {
that.pi = data;
});
this.calculate = function() {
requests.add(this.a, this.b, function(data) {
that.result = data;
});
}
}]);
index.html
<!doctype html>
<html ng-app="app">
<head></head>
<body ng-controller="myController as myCtrl">
<p>The number pi is {{myCtrl.pi}}</p>
<input type="number" ng-model="myCtrl.a">
<input type="number" ng-model="myCtrl.b">
<input type="button" ng-click="myCtrl.calculate()" value="Calculate">
<p>Result : {{myCtrl.result}}</p>
<script type="text/javascript" src="angular.min.js"></script>
<script type="text/javascript" src="katia-requests.js"></script>
<script type="text/javascript" src="app.js"></script>
</body>
</html>
server
app.js
var express = require('express');
var katiaRequests = require('katia-requests');
var app = express();
app.use(express.static(__dirname + '/public'));
app.use(katiaRequests(__dirname + '/functions.js'));
app.listen(8080, function () {
console.log("Server listening at port 8080 ...");
});
functions.js
module.exports = {
add: function(a, b, done, session) {
if (typeof a === 'number' && typeof b === 'number')
done(a+b);
},
pi: function(done, session) {
done(3.14);
}
}
2. Display articles from a database
client
app.js
angular.module('app', ['katia-requests'])
.controller('myController', ['katiaRequests', function(requests) {
var that = this;
requests.getArticles(function (data) {
that.articles = data;
})
}]);
index.html
<!doctype html>
<html ng-app="app">
<head></head>
<body ng-controller="myController as myCtrl">
<div ng-repeat="article in myCtrl.articles">
<h1>{{article.title}}</h1>
<p>{{article.body}}</p>
</div>
<script type="text/javascript" src="angular.min.js"></script>
<script type="text/javascript" src="katia-requests.js"></script>
<script type="text/javascript" src="app.js"></script>
</body>
</html>
server
app.js
var express = require('express');
var katiaRequests = require('katia-requests');
var app = express();
app.use(express.static(__dirname + '/public'));
app.use(katiaRequests(__dirname + '/functions.js'));
app.listen(8080, function () {
console.log("Server listening at port 8080 ...");
});
functions.js
var connection = mysql.createConnection({
host: "localhost",
user: "root",
password: "****",
database: "katia-db"
});
connection.connect();
module.exports.getArticles = function(done, session) {
connection.query('SELECT title, body FROM Article', function(err, rows) {
if (err) console.log(err);
done(rows);
});
}
3. Authentification controller
client
app.js
angular.module('app', ['katia-requests'])
.controller('myController', ['katiaRequests', function(requests) {
var that = this;
this.message = "A message";
this.resetMessage = function() {
this.message = "A message";
}
this.authentificateAsMember = function() {
requests.authentificateAsMember(function() {});
};
this.authentificateAsAdmin = function() {
requests.authentificateAsAdmin(function() {});
};
this.unauthentificate = function() {
requests.unauthentificate(function() {});
};
this.callAdminFunction = function () {
requests.adminFunction(function(data) {
that.message = data;
});
}
this.callMemberFunction = function () {
requests.memberFunction(function(data) {
that.message = data;
});
}
}]);
index.html
<!doctype html>
<html ng-app="app">
<head></head>
<body ng-controller="myController as myCtrl">
<button ng-click="myCtrl.authentificateAsAdmin()">authentificate as admin</button>
<button ng-click="myCtrl.authentificateAsMember()">authentificate as member</button>
<button ng-click="myCtrl.unauthentificate()">unauthentificate</button>
<br>
<button ng-click="myCtrl.resetMessage()">reset message</button>
<button ng-click="myCtrl.callAdminFunction()">call admin function</button>
<button ng-click="myCtrl.callMemberFunction()">call member function</button>
<div>
{{myCtrl.message}}
</div>
<script type="text/javascript" src="angular.min.js"></script>
<script type="text/javascript" src="katia-requests.js"></script>
<script type="text/javascript" src="app.js"></script>
</body>
</html>
server
app.js
var express = require('express');
var katiaRequests = require('katia-requests');
var session = require('express-session');
var app = express();
app.use(session({
resave: false,
saveUninitialized: true,
secret: 'my secret'
}));
function restrictMember(req, res, next) {
if (req.session && req.session.member)
next();
else {
res.send('Access denied');
console.log('Not authentificated as a member !');
}
}
function restrictAdmin(req, res, next) {
if (req.session && req.session.admin)
next();
else {
res.send('Access denied');
console.log('Not authentificated as an admin !');
}
}
app.use(katiaRequests(__dirname + '/functionsAuthentification.js'));
app.use(katiaRequests(__dirname + '/functionsMember.js', {restrict : restrictMember}));
app.use(katiaRequests(__dirname + '/functionsAdmin.js', {restrict : restrictAdmin}));
app.use(express.static(__dirname + '/public'));
app.listen(8080, function () {
console.log("Server listening at port 8080 ...");
});
functionsAuthentification.js
var id = 1;
module.exports = {
authentificateAsMember: function(done, session) {
id++;
if (session.admin)
delete session.admin;
session.member = "member" + id.toString();
done();
},
authentificateAsAdmin: function(done, session) {
id++;
if (session.member)
delete session.member;
session.admin = "admin" + id.toString();
done();
},
unauthentificate: function(done, session) {
if (session.member)
delete session.member;
if (session.admin)
delete session.admin;
done();
}
}
functionsAdmin.js
module.exports = {
adminFunction: function(done, session) {
done("Hey, I'm an administrator ! My name is : " + session.admin);
}
}
functionsMember.js
module.exports = {
memberFunction: function(done, session) {
done("Hey, I'm a member ! My name is : " + session.member);
}
}
Credits
Loïc Poullain [email protected]