We’ve been using middlewares in our previous video tutorials. Today, we’ll have a look at these middlewares.
Connect is a middleware framework of Node.js
But since connect is one of the dependencies of Express, we need not install it separately. If we have installed Express, then we already have connect.
Middeware in Express: Node.js app.js
1
2
3
4
5
6
7
8
var express = require('express');
var app = express();
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(express.cookieParser());
app.use(express.session({secret: "some secret key"}));
app.use(app.router);
app.use(express.static(path.join(__dirname, 'public')));
var express = require('express');
var app = express(); app.use(express.bodyParser()); app.use(express.methodOverride()); app.use(express.cookieParser()); app.use(express.session({secret: "some secret key"})); app.use(app.router); app.use(express.static(path.join(__dirname, 'public')));
express.bodyParser extensible request body parser express.methodOverride faux HTTP method support express.cookieParser cookie parser express.session session management support with bundled MemoryStore express.static streaming static file server supporting Range and more express.directory directory listing middleware
For list of all supported middleware, visit senchalabs Also check the list of all the 3rd-party middleware supported by Connect.
Note: Ordering of these middleware is very important. For Example: 1. You can only override method after you’ve parsed the body, so methodOverride() must come only after bodyParser() 2. Similarly, session middleware depends on cookieParser(), so session middleware must come only after cookieParser()
As your application becomes popular you’ll need middlewares to handle csrf( Cross-site request forgery ), DDos attacks etc. Also it’s very important to validate the user requests before you allow the user request to fetch the data from your database. Learn to use middleware properly, and I’m sure, it’ll be a life-saver for your application.
Here we have an array of objects – which in real-time application we get from a database ( Ex: MongoDB ). Now we define a route, and get two params in a single URL. By fetching and parsing those two params, we pass it to slice method of array and get array objects within the range/limit. Also note the use of response in json formatting while sending the data using response object.
Regular Expressions in Routes: Express app.js
1
2
3
4
5
6
7
8
9
app.get(/\/user\/(\d*)\/?(edit)?/, function(req, res){
if(req.params[0])
res.send("Viewing user id: "+req.params[0]);
else if(req.params[1])
res.send("editing user with an id "+req.params[0]);
else
res.send("Enter User ID!!");
});
app.get(/\/user\/(\d*)\/?(edit)?/, function(req, res){
if(req.params[0]) res.send("Viewing user id: "+req.params[0]);
else if(req.params[1]) res.send("editing user with an id "+req.params[0]);
else res.send("Enter User ID!!");
});
we enter our regular expression between two forward slashes. And to escape the forward slash present inside our regular expression, we make use of escape character i.e., a back slash. After /user/ we can have zero or more digits, after that an optional edit keyword followed by an optional trailing forward slash.
These routes match our pattern: /user/ /user/userId/ /user/userId/edit /user/userId/edit/
Depending on which URL the user is requesting, we could serve the purpose, using conditionals.
Note: In our example we are simply displaying the view and edit modes. But in real-time applications you could replace it with some database queries and make sure the operations makes proper sense.
When we request information of particular user by using his username in the URL, it fetches the username using request object and displays appropriate message. Example: If the user requests /user/Satish it’ll output Satish’s profile!
Public Folder
If we put some files inside our public directory, it would be convenient if some middlewares fetch the files directly upon user request, instead of writing routes for all those files. Connect module which is a dependency of Express web framework takes care of this.
Middleware for public folder files app.js
1
2
3
4
5
6
var express = require('express');
var path = require('path');
var app = express();
app.use(express.static(path.join(__dirname, 'public')));
var express = require('express');
var path = require('path');
var app = express(); app.use(express.static(path.join(__dirname, 'public')));
If you want your custom routes to be checked before the public folder, then you could specify it using another middleware, i.e., app.router
Note that, the ordering of Middleware is significant.
Sending HTML in Routs: Express app.js
1
2
3
4
5
6
7
8
9
10
app.get('/', function(req, res){
var msg = [
"<h1>I love Google..</h1>",
"<p>Because they make awesome products",
"<br />like my Nexus 7 Tablet",
"which is so amazing!"
].join("\n");
res.send(msg);
});
</p>
app.get('/', function(req, res){ var msg = [ "<h1>I love Google..</h1>", "<p>Because they make awesome products", "<br />like my Nexus 7 Tablet", "which is so amazing!" ].join("\n"); res.send(msg);
});
</p>
This would out put with all HTML semantics on the browser.
Get, Post, Put, Delete Requests Web browsers by default support only get and post requests. But we can override methods and make sure our Node.js application supports even the Put and Delete requests.
Post Request HTML Form index.html present in public directory
Here we have a form with post method and also take note of action field value.
POST Route app.js
1
2
3
4
5
app.use(express.bodyParser());
app.post('/user', function(req, res){
res.send("Submitted user's name is: "+req.body.name);
});
app.use(express.bodyParser());
app.post('/user', function(req, res){ res.send("Submitted user's name is: "+req.body.name);
});
Inorder to parse the HTML page, you’ll need bodyParser middleware. Once you have it in place you can get form field entries and use it to insert the data into database or simply display as in our case with this example.
We could similarly write code for PUT and DELETE requests. PUT & DELETE Routes app.js
1
2
3
4
5
6
7
8
9
10
app.use(express.bodyParser());
app.use(express.methodOverride());
app.put('/user/:userId', function(req, res){
res.send("Editing user with userid: "+req.params.userId);
});
app.delete('/user/:userId', function(req, res){
res.send("Editing user with userid: "+req.params.userId);
});
app.use(express.bodyParser());
app.use(express.methodOverride());
app.put('/user/:userId', function(req, res){ res.send("Editing user with userid: "+req.params.userId);
});
app.delete('/user/:userId', function(req, res){ res.send("Editing user with userid: "+req.params.userId);
});
By getting the unique userId of the user, you could fetch the data from database and make changes and update the information using Put request. Similarly, using the unique userId of the user, you could select and delete the information about the user!
Separating Route Files As your application grows, its hard to keep the code cleaner and maintainable, so it’s always a good idea to separate these kind of information from the main application file. So we create a file called routes and include it as a local module in our main application file.
External Route File /routes/index.js
1
2
3
4
5
6
7
/*
* GET home page.
*/
exports.index = function(req, res){
res.send('Google Nexus 5 To Be Release Shortly ..');
};
/* * GET home page. */exports.index = function(req, res){ res.send('Google Nexus 5 To Be Release Shortly ..');
};
exports is a global provided by node.js index is a name given by us; it’s a property name and we assign a function to it.
Accessing External Route File app.js
1
2
3
var routes = require('./routes');
app.get('/', routes.index);
var routes = require('./routes');
app.get('/', routes.index);
This would output: Google Nexus 5 To Be Release Shortly ..
You may often want different settings for development environment and a different settings in the production environment. Also you could keep pushing the files to server for testing. So you’ll need to test your application in two different environments: development & production
In situations like this, you could have environment specific configurations using express. In this video tutorial, I’ll be walking you through setting up configurations for these environments using Express, web framework of Node.js.
Main application file app.js
1
2
3
4
5
6
7
8
9
10
var express = require('express');
var app = express();
// all environments
app.set('port', process.env.PORT || 3000);
app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
app.set('view cache', true);
// app.enable('view cache');
var express = require('express');
var app = express();
// all environments
app.set('port', process.env.PORT || 3000);
app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
app.set('view cache', true);
// app.enable('view cache');
Here we create an express object, using which we set the configurations. First we set the port number to whatever is set by the server – which is present in the environment variable process.env.PORT if it is not set use 3000 as port number. Next, assign views a directory: root directory( __dirname ) and views folder. You could create any folder inside root and assign it to views. Then, set default view engine as Jade. Next we enable the view cache – btw View caching is useful in production environment.
Development Environment app.js
1
2
3
4
// development only
if ('development' == app.get('env')) {
app.use(express.errorHandler());
}
// development only
if ('development' == app.get('env')) { app.use(express.errorHandler());
}
Here we could list all the settings needed for our development environment.
Production Environment app.js
1
2
3
4
// production only
if ('production' == app.get('env')) {
app.enable('view cache');
}
// production only
if ('production' == app.get('env')) { app.enable('view cache');
}
Here we could list all the settings needed for our production environment.
Mixins in Jade are much like functions/methods in many other programming languages.
Basically, if you’re repeating your code at many places, you could place that code inside a mixin and replace your code with the mixin call. This would make your code cleaner and maintainable over long run.
Here we have included the mixin.jade file, and now use our fetch mixin and pass-in our array variable, which is converted into an unordered list of items and output on the browser.
Note: Clearly, in real-time applications the array or object come from the database. Example: You might encounter the situation to list out all the users in your list and list of all the participating companies. Or list of all companies someone has worked at. In such cases you’ll get an array of objects which you need to out put to the user in a well formatted manner. In situations like this, mixins are a great tool to have, to avoid the necesity to repeat your code allover your application.
Have all your mixins in a single file and then include that file wherever you are calling your mixins.