Node.js is javascript runtime for the server side applications. It allows you to do almost anything that an established server side language can do (e.g: Java, C#).
Node.js is a library of components that is written for the V8 engine and provides common libraries (e.g: HTTP, Crypto, Buffer) and familiar integrations with the OS i.e file system, sockets etc. However, the key differentiator is nodejs is a non blocking, even-driven framework. In the event driven model, any time consuming operation is executed asynchronously, via callback functions. The callbacks get registered with the nodejs runtime and are invoked when the operation completes and results needs to be passed back to your application. For example, when querying a database, calling query on the connection fires the query to the database, however the executing thread does not wait for the results. The result from the query is passed to a callback function passed as an argument to the query method. The main thread is always available for processing new requests. All asynchronous invocations are processed by a separate pool of threads maintained by the nodejs runtime.
Note that nodejs is single threaded i.e if the main thread is blocked due to a synchronous method, no other requests can be processed until the blocked method completes. So although it is possible do I/O operations synchronously, it is advised to perform then via asynchronous callbacks instead.
In this blog, you will learn how to build a simple web application for displaying film listings from a database.
The following frameworks are used
- express - a web application frameworks for building single or multi page applications
- sequelize - an ORM tool for databases
- sqlite3 - a light weight, embedded database engine that requires zero-configuration
- handlebars - a template engine for displaying views
- log4js - logging framework
We will use the following directory structure for our movie-rental project
+-- filmsApp
+-- main
¦ app.js
¦ package.json
¦ +-- models
¦ film.js
¦ +-- repository
¦ FilmRepository.js
¦ +-- routes
¦ FilmRoute.js
¦ +-- static
¦ +-- css
¦ +-- js
¦ +-- views
¦ +-- layouts
¦ main.handlebars
¦ films.handlebars
+-- test
+-- database
¦ films.db
Express - the web application framework
Express is a web framework for node. To install express, run the following npm command. The --save option adds the express module to the package.json file.
npm install --save express
The first step in creating the web app is to load the express module and create an instance of the web app using the express function.
var express = require(‘express’);
var app = express();
Note that require() function loads the module only once i.e repeated calls to the function returns the same cached instance.
Now add routes, which define how request paths are mapped to routing functions in our app. Routing defines a mapping between a request path and a middleware function i.e a function that processes the request and sends back a response to the browser. Route methods are derived from HTTP methods i.e GET, POST etc. To register a route path / for the HTTP GET method, use the app objects “get” method and a function callback that receives the request and response objects
var filmsRoute = require('./routes/FilmRoute');
app.use('/films', filmsRoute);
In the above code, the /films request path is mapped to the middleware function defined in the FilmRoute.js module, using the express.Router() function.
class FilmRoute
{
constructor() {
this._filmRepository = require("../repository/FilmRepository");
this._router = require('express').Router();
this.registerPaths();
}
registerPaths() {
var self = this;
this._router.get("/list", function(req, res, next) {
self.getFilms(req,res,next);
});
}
getFilms(req, res, next) {
this._filmRepository.getFilms(function(films) {
res.render("films", {
films : films
});
});
}
}
var filmsRoute = new FilmsRoute();
module.exports = filmsRoute.router;
Static files like images, css and browser javascript do not require route mappings. The code below registers all paths for static files and allows us to refer them in generated browser html.
app.use("/static", express.static(path.join(__dirname, '/static')));
Handlebars - the view engine
The next step is creating the view template engine. We will be using handlebars, one of the most popular view engines for node and my favourite. Handlebars is a template engine for node, similar to what jsp is for java. It provides conditional and loop constructs to build dynamic web pages from objects in the response. You can install handlebars and express-handlebars integration modules using the following npm command
npm install --save express-handlebars
To initialise the handlebars engine in app.js
var exphbs = require('express-handlebars');
var hbs = exphbs.create({defaultLayout: 'main'});
app.engine('handlebars', hbs.engine);
app.set('view engine', 'handlebars');
By default, handlebars expects view files to be present in the views directory. This can however be changed if required. In the handlebars configuration, we have specified main.handlebars as the default layout. This is the layout that every view in our application extends.
SQLite - the database
SQLite database is a self contained, server less, zero configuration database. We will be using SQLite to store data for our film application. I have created our database films.db file with data extracted from the MySQL Sakila database (http://downloads.mysql.com/docs/sakila-db.zip) and stored it in the database directory as films.db
Install sqlite3 using npm command
npm install --save sqlite3
Sequelize - the ORM tool
Sequelize is an ORM framework for node, with support for accessing a SQLite database in additional to other popular databases. It allows us to map the database tables to model objects in node. This simplifies querying and updating of data via model objects, without need to hand craft any queries or DML statements.
To install Sequelize, run the following npm command
npm install --save sequelize
First create a sequelize instance with SQLite as the database, by specifying the sqlite dialect and providing path to the database storage file
var Sequelize = require('sequelize');
var sequelize = new Sequelize('', '', '', {
dialect: 'sqlite',
pool: {
max: 5,
min: 0,
idle: 10000
},
storage: '../database/films.db'
});
Then create a object to table mapping for the film table in models/films.js , using sequelize.define()
module.exports = function(sequelize, DataTypes) {
return sequelize.define('film', {
filmId : {
type : DataTypes.INTEGER,
primaryKey : true,
field : 'film_id',
},
title : {
type : DataTypes.STRING,
field : 'title'
},
rentalRate : {
type : DataTypes.REAL,
field : 'rental_rate'
}
}, {
timestamps : false,
freezeTableName : false,
tableName : 'film'
});
}
and then import the model into sequelize using the import functionsequelize.import("./models/film.js");
The database connection pool should be initialized before we start accepting requests to our app. To ensure this, we call the sync() method and initialised the web app in the callback function as
below
sequelize.sync().then(function(result) {
global.sequelize = sequelize;
initWebapp(); // this is where we initialise express engine
}, function(err) {
console.log('An error occurred when initialising the films database’, err);
});
Note that we are storing the sequelize instance in a global variable with the same name, so it is accessible elsewhere in the application
global.sequelize = sequelize;
The next step is to create a repository class (aka DAO) to access contents of the film table from the database
"use strict"
class FilmRepository {
constructor() {
this._sequelize = global.sequelize;
}
getFilms(callback) {
this._sequelize.models['film'].all({limit:10}).then(callback);
}
}
module.exports = new FilmRepository();
This repository is injected into the FilmsRoute.js constructor, using the require() function.Finally, to start the webapp on a specific port, add the following line of code as the last step
app.listen(3000);
To run the app, open an command prompt and run the following command from the app base directory
$ node app.js
Open a browser and type the following URL in the address bar
http://localhost:3000/films/list
Code for this app is available for download on github.
Very informative. Thank you.
ReplyDeleteWell presented and precise blog about Nodejs!! Definitely a wonderful starting point for someone who is new to the language.
ReplyDeleteThank you
excellent tutorial, except now it needs a sequel (part two). thank you very much.
ReplyDeleteMerkur Super Stainless Steel - Xn--o80b910a26eepc81il5g.online
ReplyDeleteXn--o80b910a26eepc81il5g.Online Merkur Super Stainless Steel 3 Piece Double Edge Safety Razor, Chrome, Black, Chrome, xn--o80b910a26eepc81il5g.Online Merkur 메리트 카지노 쿠폰 Super Stainless Steel 3 Piece Double Edge 바카라 Safety 제왕 카지노 Razor, Chrome, Black, Chrome,