Foundations

Exclusive offer: get 50% off this eBook here
Advanced Express Web Application Development

Advanced Express Web Application Development — Save 50%

Your guide to building professional real-world web applications with Express with this book and ebook.

$23.99    $12.00
by Andrew Keig | November 2013 | Open Source Web Development

This article by Andrew Keig, the author of the book Advanced Express Web Application Development, demonstrates how to install Node.js and install Express globally. It also shows how to test our Express with Mocha and SuperTest. The various ways of logging into our application is also shown.

(For more resources related to this topic, see here.)

Installation

If you do not have node installed, visit: http://nodejs.org/download/.

There is also an installation guide on the node GitHub repository wiki if you prefer not to or cannot use an installer: https://github.com/joyent/node/wiki/Installation.

Let's install Express globally:

npm install -g express

If you have downloaded the source code, install its dependencies by running this command:

npm install

Testing Express with Mocha and SuperTest

Now that we have Express installed and our package.json file in place, we can begin to drive out our application with a test-first approach. We will now install two modules to assist us: mocha and supertest.

Mocha is a testing framework for node; it's flexible, has good async support, and allows you to run tests in both a TDD and BDD style. It can also be used on both the client and server side. Let's install Mocha with the following command:

npm install -g mocha –-save-dev

SuperTest is an integration testing framework that will allow us to easily write tests against a RESTful HTTP server. Let's install SuperTest:

npm install supertest –-save-dev

Continuous testing with Mocha

One of the great things about working with a dynamic language and one of the things that has drawn me to node is the ability to easily do Test-Driven Development and continuous testing. Simply run Mocha with the -w watch switch and Mocha will respond when changes to our codebase are made, and will automatically rerun the tests:

mocha -w

Extracting routes

Express supports multiple options for application structure. Extracting elements of an Express application into separate files is one option; a good candidate for this is routes.

Let's extract our route heartbeat into ./lib/routes/heartbeat.js; the following listing simply exports the route as a function called index:

exports.index = function(req, res){ res.json(200, 'OK'); };

Let's make a change to our Express server and remove the anonymous function we pass to app.get for our route and replace it with a call to the function in the following listing. We import the route heartbeat and pass in a callback function, heartbeat.index:

var express = require('express') , http = require('http') , config = require('../configuration') , heartbeat = require('../routes/heartbeat') , app = express(); app.set('port', config.get('express:port')); app.get('/heartbeat', heartbeat.index); http.createServer(app).listen(app.get('port')); module.exports = app;

404 handling middleware

In order to handle a 404 Not Found response, let's add a 404 not found middleware. Let's write a test, ./test/heartbeat.js; the content type returned should be JSON and the status code expected should be 404 Not Found:

describe('vision heartbeat api', function(){ describe('when requesting resource /missing', function(){ it('should respond with 404', function(done){ request(app) .get('/missing') .expect('Content-Type', /json/) .expect(404, done); }) }); });

Now, add the following middleware to ./lib/middleware/notFound.js. Here we export a function called index and call res.json, which returns a 404 status code and the message Not Found. The next parameter is not called as our 404 middleware ends the request by returning a response. Calling next would call the next middleware in our Express stack; we do not have any more middleware due to this, it's customary to add error middleware and 404 middleware as the last middleware in your server:

exports.index = function(req, res, next){ res.json(404, 'Not Found.'); };

Now add the 404 not found middleware to ./lib/express/index.js:

var express = require('express') , http = require('http') , config = require('../configuration') , heartbeat = require('../routes/heartbeat') , notFound = require('../middleware/notFound') , app = express(); app.set('port', config.get('express:port')); app.get('/heartbeat', heartbeat.index); app.use(notFound.index); http.createServer(app).listen(app.get('port')); module.exports = app;

Logging middleware

Express comes with a logger middleware via Connect; it's very useful for debugging an Express application. Let's add it to our Express server ./lib/express/index.js:

var express = require('express') , http = require('http') , config = require('../configuration') , heartbeat = require('../routes/heartbeat') , notFound = require('../middleware/notFound') , app = express(); app.set('port', config.get('express:port')); app.use(express.logger({ immediate: true, format: 'dev' })); app.get('/heartbeat', heartbeat.index); app.use(notFound.index); http.createServer(app).listen(app.get('port')); module.exports = app;

The immediateoption will write a log line on request instead of on response. The devoption provides concise output colored by the response status. The logger middleware is placed high in the Express stack in order to log all requests.

Logging with Winston

We will now add logging to our application using Winston; let's install Winston:

npm install winston --save

The 404 middleware will need to log 404 not found, so let's create a simple logger module, ./lib/logger/index.js; the details of our logger will be configured with Nconf. We import Winston and the configuration modules. We define our Logger function, which constructs and returns a file logger—winston.transports. File—that we configure using values from our config. We default the loggers maximum size to 1 MB, with a maximum of three rotating files. We instantiate the Logger function, returning it as a singleton.

var winston = require('winston') , config = require('../configuration'); function Logger(){ return winston.add(winston.transports.File, { filename: config.get('logger:filename'), maxsize: 1048576, maxFiles: 3, level: config.get('logger:level') }); } module.exports = new Logger();

Let's add the Loggerconfiguration details to our config files ./config/ development.jsonand ./config/test.json:

{ "express": { "port": 3000 }, "logger" : { "filename": "logs/run.log", "level": "silly", } }

Let's alter the ./lib/middleware/notFound.js middleware to log errors. We import our logger and log an error message via logger when a 404 Not Found response is thrown:

var logger = require("../logger"); exports.index = function(req, res, next){ logger.error('Not Found'); res.json(404, 'Not Found'); };

Summary

This article has shown in detail with all the commands how Node.js is installed along with Express. The testing of our Express with Mocha and SuperTest is shown in detail. The logging in into our application is shown with middleware and Winston.

Resources for Article:


Further resources on this subject:


Advanced Express Web Application Development Your guide to building professional real-world web applications with Express with this book and ebook.
Published: November 2013
eBook Price: $23.99
Book Price: $39.99
See more
Select your format and quantity:

About the Author :


Andrew Keig

Andrew Keig is a London based web developer who has been building web applications since 2000. He is the author of Packt's Instant RabbitMQ Messaging Application Development How-to. Andrew has a degree in Computing and blogs at blog.airasoul.net on topics he is passionate about, such as Node.js, REST, Web APIs, and behaviour-driven development. He also contributes to various Node.js open source projects. He is a director at Airasoul, which specializes in the design and build of scalable, RESTful, specification-driven, and real-time web-based applications on the Node.js stack. He is also the co-founder of openue.com, a property search startup.

Books From Packt


SproutCore Web Application Development
SproutCore Web Application Development

Real-time Web Application Development using Vert.x 2.0
Real-time Web Application Development using Vert.x 2.0

Symfony 1.3 Web Application Development
Symfony 1.3 Web Application Development

Grails 1.1 Web Application Development
Grails 1.1 Web Application Development

IBM Lotus Domino: Classic Web Application Development Techniques
IBM Lotus Domino: Classic Web Application Development Techniques

CherryPy Essentials: Rapid Python Web Application Development
CherryPy Essentials: Rapid Python Web Application Development

Apache Struts 2 Web Application Development
Apache Struts 2 Web Application Development

 Instant Apache Camel Messaging System [Instant]
Instant Apache Camel Messaging System [Instant]


No votes yet

Post new comment

CAPTCHA
This question is for testing whether you are a human visitor and to prevent automated spam submissions.
r
3
y
X
3
3
Enter the code without spaces and pay attention to upper/lower case.
Code Download and Errata
Packt Anytime, Anywhere
Register Books
Print Upgrades
eBook Downloads
Video Support
Contact Us
Awards Voting Nominations Previous Winners
Judges Open Source CMS Hall Of Fame CMS Most Promising Open Source Project Open Source E-Commerce Applications Open Source JavaScript Library Open Source Graphics Software
Resources
Open Source CMS Hall Of Fame CMS Most Promising Open Source Project Open Source E-Commerce Applications Open Source JavaScript Library Open Source Graphics Software