Prash's Blog

Basic Nodejs Application May 1, 2012

Filed under: Nodejs — prazjain @ 11:57 am
Tags:

This is part of a multipart nodejs series.

Here I will write a basic nodejs application and then we will go ahead and make changes to this app to make it faster and better as we go along.
Lets make a calculator web application in nodejs. We do not need any external dependencies for this application.

PS: In some places you will need to change ” (double quote) for a ‘ (single quote) in javascript for the code below. WordPress goes mental if I use ‘ (single quote) in my javascript code.
PS2 : WordPress also goes mental if I use div tag in my code!

In app-node.js we are creating a http server and redirecting particular requests to particular modules. Code for the modules follows later.
Create module app-node.js with contents from below.

var http_port = 8124;
var http = require("http");
var htutil =require("./htutil");

var server = http.createServer(function(req,res)
				{
					htutil.loadParams(req,res,undefined);
					if (req.params.pathname==="/")
					{
						require("./home-node").get(req,res);
					}
					else if (req.params.pathname==="/square")
					{
						require("./square-node").get(req,res);
					}
					else if (req.params.pathname === "/factorial")
					{
						require("./factorial-node").get(req,res);
					}
					else if (req.params.pathname === "/fibonacci")
					{
						require("./fibo-node").get(req,res);
					}
					else if (req.params.pathname === "/mult")
					{
						require("./mult-node").get(req,res);
					}
					else
					{
						res.writeHead(404,{"Content-Type":"text/plain"});
						res.end("bad URL " + req.url);
					}
				});
server.listen(http_port);
console.log("listening to http://localhost:8124");

For Module htutil.js, use the code below. This module does a few things:
1) Parses request parameters into variables a and b and invokes a chaining function if defined.
2) Creates a navigation bar in the web app, to navigate / invoke different requests.
3) A function to render the html for web page. This takes 3 params, the title for the page, navigation bar contents and web page contents.

var url = require("url");
exports.loadParams = function(req,res,next)
{
	req.params = url.parse(req.url,true);
	req.a = (req.params.query.a && !isNaN(req.params.query.a)) ? new Number (req.params.query.a) : NaN ;
	req.b = (req.params.query.b && !isNaN(req.params.query.b)) ? new Number (req.params.query.b) : NaN ;
	if (next) next();
}
exports.navbar = function()
{
	return ["<div class="navbar">",
			"<p><a href="/">home</a></p>",
			"<p><a href="/mult">Multiplication</a></p>",
			"<p><a href="/square">Square</a></p>",
			"<p><a href="/factorial">Factorial</a></p>",
			"<p><a href="/fibonacci">Fibonacci</a></p>",
			"</div>"].join("\n");
}
exports.page= function (title, navbar, content)
{
	return ["<html><head><title>{title}</title></head>",
			"<body><h1>{title}</h1>",
			"<table><tr>",
			"<td>{navbar}</td><td>{content}</td>",
			"</tr></table></body></html>"
			].join("\n2")
			.replace(/{title}/g,title)
			.replace(/{navbar}/g,navbar)
			.replace(/{content}/g,content);
}

Now lets write module that will actually perform these calculation, there is not much to explain in them so I will just write them down.

mult-node.js

var htutil = require("./htutil");
exports.get=function(req,res)
{
	res.writeHead(200, { "Content-Type":"text/html" });
	var result = req.a * req.b;
	res.end(htutil.page("Multiplication", htutil.navbar(),
							[
							(!isNaN(req.a) && !isNaN(req.b) ?
								("<p class="result">{a} * {b} = {result}</p>"
								.replace("{a}", req.a)
								.replace("{b}", req.b)
								.replace("{result}", req.a * req.b))
								: ""
							),
							"<p>Enter numbers to multiply</p>",
							"<form name="mult" action="/mult" method="get">",
							"A: <input type="text" name="a" /><br/>",
							"B: <input type="text" name="b" /><br/>",
							"<input type="submit" value="Submit" />",
							"</form>"
							].join("\n")
						)
			);
}

Module square-node.js

var htutil = require("./htutil");
exports.get=function(req,res)
{
	res.writeHead(200, { 'Content-Type':'text/html' });
	res.end(htutil.page("Square", htutil.navbar(),
							[
							(!isNaN(req.a) ?
								("<p class='result'>{a} squared = {sq}</p>"
								.replace("{a}", req.a)
								.replace("{sq}", req.a * req.a))
								: ""
							),
							"<p>Enter number to Square</p>",
							"<form name='square' action='/square' method='get'>",
							"A: <input type='text' name='a' /><br/>",
							"<input type='submit' value='Submit' />",
							"</form>"
							].join('\n')
						)
			);
}

Module home-node.js

var htutil = require('./htutil');
exports.get = function(req,res)
{
	res.writeHead(200, { 'Content-Type':'text/html'});
	res.end(htutil.page("Math App", htutil.navbar(), "<p>Math App</p>"));
}

Module factorial-node.js

var htutil = require("./htutil");
var math = require('./math');
exports.get=function(req,res)
{
	res.writeHead(200, { 'Content-Type':'text/html' });
	res.end(htutil.page("Factorial", htutil.navbar(),
							[
							(!isNaN(req.a) ?
								("<p class='result'>{a} factorial = {fact}</p>"
								.replace("{a}", req.a)
								.replace("{fact}", math.factorial(Math.floor(req.a))))
								: ""
							),
							"<p>Enter number to find factorial</p>",
							"<form name='factorial' action='/factorial' method='get'>",
							"A: <input type='text' name='a' /><br/>",
							"<input type='submit' value='Submit' />",
							"</form>"
							].join('\n')
						)
			);
}

Module fibo-node.js

var htutil = require("./htutil");
var math = require('./math');
exports.get=function(req,res)
{
	res.writeHead(200, { 'Content-Type':'text/html' });
	res.end(htutil.page("Fibonacci", htutil.navbar(),
							[
							(!isNaN(req.a) ?
								("<p class='result'>{a} fibonacci series = {fibo}</p>"
								.replace("{a}", Math.floor(req.a))
								.replace("{fibo}", math.fibonacci(Math.floor(req.a))))
								: ""
							),
							"<p>Enter number to find Fibonacci</p>",
							"<form name='fibonacci' action='/fibonacci' method='get'>",
							"A: <input type='text' name='a' /><br/>",
							"<input type='submit' value='Submit' />",
							"</form>"
							].join('\n')
						)
			);
}

Finally the math.js module that has the functions to calculate factorial and fibonacci

var factorial = exports.factorial = function(n)
{
	if (n==0)
		return 1;
	else 
		return n * factorial (n-1);
}

var fibonacci = exports.fibonacci = function (n)
{
	if (n === 1)
		return 1;
	else if (n===2)
		return 1;
	else
		return fibonacci(n-1) + fibonacci(n-2);
}

Now that you have all these modules in same directory, run the command below to start your app

node app-node.js

Now hit the url : http://localhost:8124, to see the app running.
Also note that if you run fibonacci operation, its performance degrades significantly for large values, start with 10, 20, 30, 40. But if you go 50 it will takes hours / days to return back. And while you have run fibonacci operation for 50 through one request, if you try accessing your app through another browser window you will notice that the server does not respond back. This is because node is single threaded and blocks on this operation. In next post we will see how to break this task into several smaller task and execute them which also keep the server responsive enough to handle other requests.

Go back to the main nodejs tutorial.

Advertisements
 

One Response to “Basic Nodejs Application”


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s