nodejs

38
By, Predhin Tom Sapru

Upload: predhin-sapru

Post on 11-Jul-2015

1.137 views

Category:

Software


1 download

TRANSCRIPT

Page 1: NodeJS

By,

Predhin Tom Sapru

Page 2: NodeJS

Contents Introduction .................................................................................................................................................. 3

What is NodeJS? ............................................................................................................................................ 4

Why NodeJS? ................................................................................................................................................ 6

History of NodeJS .......................................................................................................................................... 8

How Does It Work? ....................................................................................................................................... 9

NPM: The Node Package Manager ............................................................................................................. 11

Where Node.js Can Be Used ....................................................................................................................... 12

Where Node.js Shouldn’t Be Used .............................................................................................................. 13

Fundamentals of NodeJS ............................................................................................................................ 14

Installing NodeJS ......................................................................................................................................... 21

Let’s Say Hello to NodeJS ............................................................................................................................ 21

NODE.JS AND EXPRESS - CREATING A REST API .......................................................................................... 25

Express application generator .................................................................................................................... 31

Taking Baby Steps with Node.js – Debugging with node-inspector ........................................................... 34

Summarizing NodeJS ................................................................................................................................... 38

Page 3: NodeJS

Introduction

About this module

This module provides students with the knowledge and skills that are needed to

develop applications by using the NodeJS.

Target Audience

This module is designed for beginners of NodeJS who are expected to know the basic

concepts of Javascript.

Module Objectives

After completing this module handout, you will be able to:

Describe the features and characteristics of NodeJS

o What is NodeJS?

o Why NodeJS?

o What advantage does NodeJS brings in?

Define NodeJS

Create a NodeJS application

Run and Debug a NodeJS application

Pre-requisite

The prerequisite of NodeJS is knowledge in concepts of Javascript.

Page 4: NodeJS

What is NodeJS? Node.js® is a platform built on Chrome's JavaScript runtime for easily building

fast, scalable network applications. Node.js uses an event-driven, non-blocking I/O

model that makes it lightweight and efficient, perfect for data-intensive real-time

applications that run across distributed devices.

Chances are good that you are familiar with asynchronous programming; it is, after all,

the "A" in Ajax. Every function in Node.js is asynchronous. Therefore, everything that

would normally block the thread is instead executed in the background. This is the most

important thing to remember about Node.js. For example, if you are reading a file on

the file system, you have to specify a callback function that is executed when the read

operation has completed.

You are Doing Everything!

Node.js is only an environment - meaning that you have to do everything yourself.

There is not a default HTTP server, or any server for that matter. This can be

overwhelming for new users, but the payoff is a high performing web app. One script

handles all communication with the clients. This considerably reduces the number of

resources used by the application.

Node.js is an open source project designed to help you write JavaScript programs that

talk to networks, file systems or other I/O (input/output, reading/writing) sources. That's

it! It is just a simple and stable I/O platform that you are encouraged to build modules

on top of.

What are some examples of I/O? Here is a diagram of an application that shows many

I/O sources:

Page 5: NodeJS

The point is to show that a single node process (the hexagon in the middle) can act as

the broker between all of the different I/O endpoints (orange and purple represent I/O).

Usually building these kinds of systems is either:

difficult to code but yields superfast results (like writing your web servers from

scratch in C)

easy to code but not very speedy/robust (like when someone tries to upload a

5GB file and your server crashes)

Node's goal is to strike a balance between these two: relatively easy to understand and

use and fast enough for most use cases.

Node isn't either of the following:

A web framework (like Rails or Django, though it can be used to make such

things)

A programming language (it uses JavaScript but node isn't its own language)

Instead, node is somewhere in the middle. It is:

Designed to be simple and therefore relatively easy to understand and use

Page 6: NodeJS

Useful for I/O based programs that need to be fast and/or handle lots of

connections

At a lower level, node can be described as a tool for writing two major types of

programs:

Network programs using the protocols of the web: HTTP, TCP, UDP, DNS and SSL

Programs that read and write data to the filesystem or local processes/memory

Node does I/O in a way that is asynchronous which lets it handle lots of different things

simultaneously. For example, if you go down to a fast food joint and order a

cheeseburger they will immediately take your order and then make you wait around

until the cheeseburger is ready. In the meantime they can take other orders and start

cooking cheeseburgers for other people. Imagine if you had to wait at the register for

your cheeseburger, blocking all other people in line from ordering while they cooked

your burger! This is called blocking I/O because all I/O (cooking cheeseburgers)

happens one at a time. Node, on the other hand, is non-blocking, which means it can

cook many cheeseburgers at once.

After over 20 years of stateless-web based on the stateless request-response paradigm, we

finally have web applications with real-time, two-way connections.

Node.js shines in real-time web applications employing push technology over

websockets. What is so revolutionary about that? Well, after over 20 years of stateless-

web based on the stateless request-response paradigm, we finally have web

applications with real-time, two-way connections, where both the client and server can

initiate communication, allowing them to exchange data freely. This is in stark contrast

to the typical web response paradigm, where the client always initiates communication.

Additionally, it’s all based on the open web stack (HTML, CSS and JS) running over the

standard port 80.

Why NodeJS? JavaScript’s rising popularity has brought with it a lot of changes, and the face of web

development today is dramatically different. The things that we can do on the web

nowadays with JavaScript running on the server, as well as in the browser, were hard to

Page 7: NodeJS

imagine just several years ago, or were encapsulated within sandboxed environments

like Flash or Java Applets.

As Wikipedia states ―Node.js is a packaged compilation of Google’s V8 JavaScript

engine, the libuv platform abstraction layer, and a core library, which is itself primarily

written in JavaScript.‖ Beyond that, it’s worth noting that Ryan Dahl, the creator of

Node.js, was aiming to create real-time websites with push capability, ―inspired by

applications like Gmail‖. In Node.js, he gave developers a tool for working in the non-

blocking, event-driven I/O paradigm.

After over 20 years of stateless-web based on the stateless request-response paradigm, we

finally have web applications with real-time, two-way connections.

Before digging into Node.js, you might want to read up on the benefits of using

JavaScript across the stack which unifies the language and data format (JSON), allowing

you to optimally reuse developer resources. As this is more a benefit of JavaScript than

Node.js specifically, we won’t discuss it much here. But it’s a key advantage to

incorporating Node in your stack.

In one sentence: Node.js shines in real-time web applications employing push

technology over websockets. What is so revolutionary about that? Well, after over 20

years of stateless-web based on the stateless request-response paradigm, we finally

have web applications with real-time, two-way connections, where both the client and

server can initiate communication, allowing them to exchange data freely. This is in stark

contrast to the typical web response paradigm, where the client always initiates

communication. Additionally, it’s all based on the open web stack (HTML, CSS and JS)

running over the standard port 80.

One might argue that we’ve had this for years in the form of Flash and Java Applets—

but in reality, those were just sandboxed environments using the web as a transport

protocol to be delivered to the client. Plus, they were run in isolation and often operated

over non-standard ports, which may have required extra permissions and such.

Performance and scalability are some of the feature’s that stands out best. Node is fast

too. That’s a pretty important requirement when you’re a start-up trying to make the

next big thing and want to make sure you can scale quickly, coping with an influx of

users as your site grows. Node is also perfect for offering a RESTful API - a web service

which takes a few input parameters and passes a little data back – simple data

Page 8: NodeJS

manipulation without a huge amount of computation. Node can handle thousands of

these concurrently where PHP would just collapse. Performance benefits and scalability

aside, there’s a good chance you already know some JavaScript, so why bother learning

a whole new language like PHP? And then – there’s the excitement of learning

something new and relatively uncharted. You know when something new arrives and

then becomes so ubiquitous that you regret not learning it earlier, forever playing

catchup? Don’t do that this time. Node is going to be big.

History of NodeJS Node.js was created and first published for Linux use in 2009. Its development and

maintenance was spearheaded by Ryan Dahl and sponsored by Joyent, the firm where

Dahl worked. Dahl was inspired to create Node.js after seeing a file upload progress bar

on Flickr. The browser did not know how much of the file had been uploaded and had

to query the Web server. Dahl desired an easier way. It heralded international attention

after its debut at the inaugural JSConf EU conference. Dahl's original goal was to create

the ability to make web sites with push capabilities as seen in web applications like

Gmail. After trying solutions in several other programming languages he chose

JavaScript because of the lack of an existing I/O API. This allowed him to define a

convention of non-blocking, event-driven I/O.

Node.js is a platform built around Google Chrome V8 Javascript engine, to create

lightweight, fast, scalable, event-driven and non-blocking I/O applications. So let’s begin

talking about Node.js origins, the V8 javascript engine. V8 is an opensource project by

Google and it is in the very core of Google Chrome browser. Its first public release was

on September 2, 2008; same date Chrome’s first release was announced. It was a big

step forward in browsers’ performance, and it pushed browsers’ technology to a new

whole level. It’s written in C++ and its biggest revolution was that it precompiled the

Javascript source code to machine code instead of just interpret it and then applied a JIT

process again in runtime to improve dynamic code execution. Then, around 2009, Ryan

Dahl was trying to solve a tough problem in that days: making the browser know how

much time of an upload process was left. Inspired by Ruby’s Mongrel webserver and by

the recent release of Chrome and V8, he decided to give Javascript a chance, creating

the seeds that would transform in short time into Node.js.

Page 9: NodeJS

Historically, Javascript browser environments are limited to just one execution process /

thread, making impossible to update DOM and execute some business logic

simultaneously, and this also applied to V8, so, why someone would be interested in

such limited and poor performance platform to run in a server environment?

Well, truth is that maybe Javascript is not the most calculation efficient language

available, but its event-driven non-blocking design, makes Node.js one of the

lightweight platforms (runs really well in a RaspberryPI) and more performant web

platforms, competing directly with the old JEE Java Platform, PHP and Ruby.

How Does It Work? The main idea of Node.js: use non-blocking, event-driven I/O to remain lightweight and

efficient in the face of data-intensive real-time applications that run across distributed

devices.

What it really means is that Node.js is not a silver-bullet new platform that will dominate

the web development world. Instead, it’s a platform that fills a particular need. And

understanding this is absolutely essential. You definitely don’t want to use Node.js for

CPU-intensive operations; in fact, using it for heavy computation will annul nearly all of

its advantages. Where Node really shines is in building fast, scalable network

applications, as it’s capable of handling a huge number of simultaneous connections

with high throughput, which equates to high scalability.

How it works under-the-hood is pretty interesting. Compared to traditional web-serving

techniques where each connection (request) spawns a new thread, taking up system

RAM and eventually maxing-out at the amount of RAM available, Node.js operates on a

single-thread, using non-blocking I/O calls, allowing it to support tens of thousands of

concurrent connections (held in the event loop).

Page 10: NodeJS

A quick calculation: assuming that each thread potentially has an accompanying 2 MB of

memory with it, running on a system with 8 GB of RAM puts us at a theoretical

Page 11: NodeJS

maximum of 4000 concurrent connections, plus the cost of context-switching between

threads. That’s the scenario you typically deal with in traditional web-serving techniques.

By avoiding all this, Node.js achieves scalability levels of over 1M concurrent

connections. There is, of course, the question of sharing a single thread between all

clients’ requests, and it is a potential pitfall of writing Node.js applications. Firstly, heavy

computation could choke up Node’s single thread and cause problems for all clients

(more on this later) as incoming requests would be blocked until said computation was

completed. Secondly, developers need to be really careful not to allow an exception

bubbling up to the core (topmost) Node.js event loop, which will cause the Node.js

instance to terminate (effectively crashing the program).

The technique used to avoid exceptions bubbling up to the surface is passing errors

back to the caller as callback parameters (instead of throwing them, like in other

environments). Even if some unhandled exception manages to bubble up, there are

multiple paradigms and tools available to monitor the Node process and perform the

necessary recovery of a crashed instance (although you won’t be able to recover users’

sessions), the most common being the Forever module, or a different approach with

external system tools upstart and monit.

NPM: The Node Package Manager When discussing Node.js, one thing that definitely should not be omitted is built-in

support for package management using the NPM tool that comes by default with every

Node.js installation. The idea of NPM modules is quite similar to that of Ruby Gems: a

set of publicly available, reusable components, available through easy installation via an

online repository, with version and dependency management.

A full list of packaged modules can be found on the NPM website https://npmjs.org/, or

accessed using the NPM CLI tool that automatically gets installed with Node.js. The

module ecosystem is open to all, and anyone can publish their own module that will be

listed in the NPM repository.

Some of the most popular NPM modules today are:

Page 12: NodeJS

express - Express.js, a Sinatra-inspired web development framework for Node.js,

and the de-facto standard for the majority of Node.js applications out there

today.

connect - Connect is an extensible HTTP server framework for Node.js, providing

a collection of high performance ―plugins‖ known as middleware; serves as a base

foundation for Express.

socket.io and sockjs - Server-side component of the two most common

websockets components out there today.

Jade - One of the popular templating engines, inspired by HAML, a default in

Express.js.

mongo and mongojs - MongoDB wrappers to provide the API for MongoDB

object databases in Node.js.

redis - Redis client library.

coffee-script - CoffeeScript compiler that allows developers to write their

Node.js programs using Coffee.

underscore (lodash, lazy) - The most popular utility library in JavaScript,

packaged to be used with Node.js, as well as its two counterparts, which

promise better performance by taking a slightly different implementation

approach.

forever - Probably the most common utility for ensuring that a given node script

runs continuously. Keeps your Node.js process up in production in the face of any

unexpected failures.

The list goes on. There are tons of really useful packages out there, available to all (no

offense to those that I’ve omitted here).

Where Node.js Can Be Used

SERVER-SIDE WEB APPLICATIONS

Page 13: NodeJS

Node.js with Express.js can also be used to create classic web applications on the server-

side. However, while possible, this request-response paradigm in which Node.js would

be carrying around rendered HTML is not the most typical use-case. There are

arguments to be made for and against this approach. Here are some facts to consider:

Pros:

If your application doesn’t have any CPU intensive computation, you can build it in

Javascript top-to-bottom, even down to the database level if you use JSON storage

Object DB like MongoDB. This eases development (including hiring) significantly.

Crawlers receive a fully-rendered HTML response, which is far more SEO-friendly than,

say, a Single Page Application or a websockets app run on top of Node.js.

Cons:

Any CPU intensive computation will block Node.js responsiveness, so a threaded

platform is a better approach. Alternatively, you could try scaling out the computation.

Using Node.js with a relational database is still quite a pain (see below for more detail).

Do yourself a favour and pick up any other environment like Rails, Django, or ASP.Net

MVC if you’re trying to perform relational operations.

Where Node.js Shouldn’t Be Used

SERVER-SIDE WEB APPLICATION W/ A RELATIONAL DB BEHIND

Comparing Node.js with Express.js against Ruby on Rails, for example, there is a clean

decision in favour of the latter when it comes to relational data access.

Relational DB tools for Node.js are still in their early stages; they’re rather immature and

not as pleasant to work with. On the other hand, Rails automagically provides data

access setup right out of the box together with DB schema migrations support tools and

other Gems (pun intended). Rails and its peer frameworks have mature and proven

Active Record or Data Mapper data access layer implementations, which you’ll sorely

miss if you try to replicate them in pure JavaScript.

Page 14: NodeJS

HEAVY SERVER-SIDE COMPUTATION/PROCESSING

When it comes to heavy computation, Node.js is not the best platform around. No, you

definitely don’t want to build a Fibonacci computation server in Node.js. In general, any

CPU intensive operation annuls all the throughput benefits Node offers with its event-

driven, non-blocking I/O model because any incoming requests will be blocked while

the thread is occupied with your number-crunching.

As stated previously, Node.js is single-threaded and uses only a single CPU core. When

it comes to adding concurrency on a multi-core server, there is some work being done

by the Node core team in the form of a cluster module [ref:

http://nodejs.org/api/cluster.html]. You can also run several Node.js server instances

pretty easily behind a reverse proxy via nginx.

With clustering, you should still offload all heavy computation to background processes

written in a more appropriate environment for that, and having them communicate via a

message queue server like RabbitMQ.

Even though your background processing might be run on the same server initially, such

an approach has the potential for very high scalability. Those background processing

services could be easily distributed out to separate worker servers without the need to

configure the loads of front-facing web servers.

Of course, you’d use the same approach on other platforms too, but with Node.js you

get that high reqs/sec throughput we’ve talked about, as each request is a small task

handled very quickly and efficiently.

Fundamentals of NodeJS Modules

Java or Python use the import function to load other libraries, while PHP and Ruby use

require. Node implements the CommonJS interface for modules. In Node you can also

load other dependencies using the require keyword.

For example, we can require some native modules:

var dns = require('dns');

Page 15: NodeJS

We can also require relative files:

var myFile = require('./myFile'); // loads myFile.js

To install modules from npm, either search for them on the website or on Github. The

syntax for installing an npm module locally is pretty straightforward:

$ npm install express

You can require module install from npm as you would do with the native ones, no need

to specify the absolute or relative path:

var express = require('express');

The nice thing about requiring Node modules is that they aren't automatically injected

into the global scope, but instead you just assigned them to a variable of your choice.

That means that you don't have to care about two or more modules that have functions

with the same name.

When creating your own modules, all you have to do is take care when exporting

something (wheather it's a function, an object, a number or so on). The first approach

would be to export a single object:

var person = { name: 'John', age: 20 };

module.exports = person;

The second approach requires adding properties to the exports object:

exports.name = 'John';

exports.age = 20;

A thing to note about modules is that they don't share scope, so if you want to share a

variable between different modules, you must include it into a separate module that is

then required by the other modules. Another interesting thing you should remember is

that modules are only loaded once, and after that they are cached by Node.

Unlike the browser, Node does not have a window global object, but instead has two

others: globals and process. However, you should seriously avoid adding properties on

the two.

Page 16: NodeJS

Callbacks

In asynchronous programming we do not return values when our functions are done,

but instead we use the continuation-passing style (CPS).

With this style, an asynchronous function invokes a callback (a function usually passed

as the last argument) to continue the program once the it has finished.

Below is an example that looks up IPv4 addresses for a domain:

var dns = require('dns');

dns.resolve4('www.google.com', function (err, addresses) {

if (err) throw err;

console.log('addresses: ' + JSON.stringify(addresses));

});

We have passed a callback (the inline anonymous function) as the second argument to

the dns.resolve4 asynchronous function. Once the async function has the response

ready for us it will invoke the callback, thus continuing the program execution. This is

how we make use of CPS.

Events

The standard callback pattern works well for the use cases where we want to be notified

when the async function finishes. However, there are situations that require being

notified of different events that do not occur at the same time.

Let us look at an example involving an IRC client:

var irc = require('irc');

var client = new irc.Client('irc.freenode.net', 'myIrcBot', { channels: ['#s

ample-channel'] });

client.on('error', function(message) { console.error('error: ', message);

});

client.on('connect', function() {

console.log('connected to the irc server');

});

client.on('message', function (from, to, message) {

Page 17: NodeJS

console.log(from + ' => ' + to + ': ' + message);

});

client.on('pm', function (from, message) {

console.log(from + ' => ME: ' + message);

});

We are listening to different types of events in the above example:

The connect event is emitted when the client has successfully connected to the

IRC server.

The error event is triggered in case an error occurs.

The message and pm events are emitted for incoming messages.

The events mentioned above make this situation ideal for using

the EventEmitter pattern.

The EventEmitter pattern allows implementors to emit an event to which the consumers

can subscribe if they are interested. This pattern may be familiar to you from the

browser, where it is used for attaching DOM event handlers.

Node has an EventEmitter class in core which we can use to make our own EventEmitter

objects. Let's create a MemoryWatcher class that inherits from EventEmitter and emits

two types of events:

A data event at a regular interval, representing the memory usage in bytes

An error event, in case the memory exceeds a certain limit imposed

The MemoryWatcher class will look like the following:

var EventEmitter = require('events').EventEmitter;

var util = require('util');

function MemoryWatcher(opts) {

if (!(this instanceof MemoryWatcher)) { return new MemoryWatcher();

}

opts = opts || { frequency: 30000 // 30 seconds };

EventEmitter.call(this);

var that = this; setInterval(function() {

Page 18: NodeJS

var bytes = process.memoryUsage().rss;

if (opts.maxBytes && bytes > opts.maxBytes) {

that.emit('error', new Error('Memory exceeded ' + opts.maxBytes + ' bytes'))

; }

else { that.emit('data', bytes); } }, opts.frequency);

}

util.inherits(MemoryWatcher, EventEmitter);

var mem = new MemoryWatcher({ maxBytes: 12455936, frequency: 5000 });

mem.on('data', function(bytes) { console.log(bytes); })

mem.on('error', function(err) { throw err; });

An easier way to create EventEmitter objects is to make new instances from the raw

EventEmitter class:

var EventEmitter = require('events').EventEmitter;

var emitter = new EventEmitter();

setInterval(function() { console.log(process.memoryUsage().rss); }, 30000);

Streams

Streams represent an abstract interface for asynchronously manipulating a continuous

flow of data. They are similar to Unix pipes and can be classified into five types:

readable, writable, transform, duplex and "classic".

As with Unix pipes, Node streams implement a composition operator called .pipe(). The

main benefits of using streams are that you don't have to buffer the whole data into

memory and they're easily composable.

To have a better understanding of how streams work we will create an application that

reads a file, encrypts it using the AES-256 algorithm and then compresses it using gzip.

All of this using streams, which means that for each chunk read it will encrypt and

compress it.

var fs = require('fs');

var zlib = require('zlib');

Page 19: NodeJS

var password = new Buffer(process.env.PASS || 'password');

var encryptStream = crypto.createCipher('aes-256-cbc', password);

var gzip = zlib.createGzip();

var readStream = fs.createReadStream(**filename);

// current file

var writeStream = fs.createWriteStream(**dirname + '/out.gz');

// reads current file

.pipe(encryptStream)

// encrypts

.pipe(gzip)

// compresses

.pipe(writeStream)

// writes to out file

.on('finish', function () {

// all done console.log('done');

});

Here we take a readable stream, pipe it into an encryption stream, then pipe that into a

gzip compression stream and finally pipe it into a write stream (writing the content to

disk). The encryption and compression streams are transform streams, which represent

duplex streams where the output is in some way computed from the input.

After running that example we should see a file called out.gz.

Error Handling

Error handling is one of the most important topics in Node. If you ignore errors or deal

with them improperly, your entire application might crash or be left in an inconsistent

state.

Threading

Node.js operates on a single thread, using non-blocking I/O calls, allowing it to support

tens of thousands of concurrent connections, without worrying about the cost of

Page 20: NodeJS

context-switching between threads. The design of sharing a single-thread between all

the requests means it can be used to build highly concurrent applications. The design

goal of a Node.js application is that any function performing I/O must use a callback. A

downside of this approach is that Node.js doesn't allow scaling with the number of CPU

cores of the machine it is running on.

V8

V8 is the JavaScript execution engine built for Google Chrome, open-sourced by Google

in 2008. Written in C++, V8 compiles JavaScript source code just-in-time to machine

code instead of interpreting it in real time. Node.js contains libuv to handle

asynchronous events. V8 provides the run-time for JavaScript. Libuv is an abstraction

layer for network and file system functionality on both Windows and POSIX-based

systems like Linux, Mac OS X and UNIX. The core functionality of Node.js resides in a

JavaScript library. The Node.js bindings, written in C++, connect these technologies to

each other and to the operating system.

Package management

Npm is the pre-installed package manager for the Node.js server platform. It is used to

install Node.js programs from the npm registry. By organizing the installation and

management of third-party Node.js programs, it helps developers build faster. npm is

not to be confused with the commonJS require() statement. It is not used to load code:

instead, it is used to install code and manage code dependencies from the command

line. The packages found in the npm registry can range from simple helper libraries like

underscore.js to task runners like Grunt.

Unified API

Node.js combined with a browser, a document DB (such as MongoDB or CouchDB) and

JSON offers a unified JavaScript development stack. With the increased attention to

client-side frameworks and the adaptation of what were essentially server-side

development patterns like MVC, MVP, MVVM, etc., Node.js allows the reuse of the same

model and service interface between client-side and server-side.

Event loop

Node.js registers itself with the operating system so that it is notified when a connection

is made. When a connection is made, the operating system will issue a callback. Within

Page 21: NodeJS

the Node.js runtime, each connection is a small heap allocation. Traditionally, relatively

heavyweight OS processes or threads handled each connection. Node.js, however, uses

an event loop, instead of processes or threads, to scale to millions of connections

happening at the same time [citation needed]. In contrast to other event-driven servers,

Node.js' event loop does not need to be called explicitly. Instead callbacks are defined,

and the server automatically enters the event loop at the end of the callback definition.

Node.js exits the event loop when there are no further callbacks to be performed.

Installing NodeJS Installing on Linux

You can install a pre-built version of node.js via downloads page using a .tar.gz.

Installing on Mac

You can install a pre-built version of node.js via downloads page using a .pkg or a .tar.gz.

Installing on Windows

You can install a pre-built version of node.js via downloads page using an .exe or a.msi.

Installing on SunOS

You can install a pre-built version of node.js via downloads page using a .tar.gz.

Let’s Say Hello to NodeJS Hello Console

This example is about as plain as it can get. It prints the words "Hello World" to the

terminal.

hello-console.js

// Call the console.log function.

console.log("Hello World");

You can run this by putting it in a file called "hello-console.js" and running it with

Page 22: NodeJS

node hello-console.js

Hello HTTP

A Simple HTTP server that responds to every request with the plain text message "Hello

World"

hello-http.js

// Load the http module to create an http server.

var http = require('http');

// Configure our HTTP server to respond with Hello World to all requests.

var server = http.createServer(function (request, response) {

response.writeHead(200, {"Content-Type": "text/plain"});

response.end("Hello World\n");

});

// Listen on port 8000, IP defaults to 127.0.0.1

server.listen(8000);

// Put a friendly message on the terminal

console.log("Server running at http://127.0.0.1:8000/");

Hello TCP

Node also makes an excellent TCP server, and here is an example that responds to all

TCP connections with the message "Hello World" and then closes the connection.

hello-tcp.js

// Load the net module to create a tcp server.

var net = require('net');

// Creates a new TCP server. The handler argument is automatically set as a listener for the 'connection' event

var server = net.createServer(function (socket) {

// Every time someone connects, tell them hello and then close the connection.

Page 23: NodeJS

console.log("Connection from " + socket.remoteAddress);

socket.end("Hello World\n");

});

// Fire up the server bound to port 7000 on localhost

server.listen(7000, "localhost");

// Put a friendly message on the terminal

console.log("TCP server listening on port 7000 at localhost.");

Hello Router

This example shows an HTTP server that responds with "Hello World" to all requests to

"/" and responds with a 404 error to everything else.

hello-router.js

// Load the node-router library by creationix

var server = require('node-router').getServer();

// Configure our HTTP server to respond with Hello World the root request

server.get("/", function (request, response) {

response.simpleText(200, "Hello World!");

});

// Listen on port 8080 on localhost

server.listen(8000, "localhost");

In order to test this, install the node-router library. There are two ways to do this. You

can either install it into a path that node recognizes or put the node-router.js file in your

application and reference it locally.

Making our response more interesting

Hello world is pretty boring so let's do something a little more entertaining. We can

create a user counter very easily in Node.js and we don't even need to use a database

like we might do in PHP.

Page 24: NodeJS

Create a new JavaScript file called, 'counter.js' and type the following:

var http = require('http');

var userCount = 0;

http.createServer(function (request, response) {

console.log('New connection');

userCount++;

response.writeHead(200, {'Content-Type': 'text/plain'});

response.write('Hello!\n');

response.write('We have had '+userCount+' visits!\n');

response.end();

}).listen(8080);

console.log('Server started');

Now let's run it with the command,

node counter.js

When you navigate your browser to 'http://localhost:8080' you should now get a view

counter.

Note: You might see the counter going up by two for each request; this is because your

browser is requesting the favicon from the server (http://localhost:8080/favicon.ico).

You should also see that Node.js is logging each request it receives to the console.

The main thing we're doing here is setting a 'userCount' variable and incrementing on

each request. We're then writing the 'userCount' in the response text.

Page 25: NodeJS

NODE.JS AND EXPRESS - CREATING

A REST API

Once you learn a little bit of Node.js you find that modules make life much easier. One

of the most popular and useful is Express. It carries a lot of similarities to the Ruby

framework, Sinatra. This makes it a great tool for building REST APIs. This example will

teach how to use Express and build a basic REST API.

Express js is a minimal and flexible node.js web application framework, providing a robust

set of features for building single and multi-page, and hybrid web applications,Express

provides a thin layer of features fundamental to any web application, without obscuring

features that you know and love in node.js, expressjs.com

Project Skeleton using ExpressJS

Every nodeJS project must have a package.json file. Creation of package.json is too cool

with npm.

The first method:

npm init

This will create package.json inside our project directory. Add the details of the

application in that package.json file like following.

{

"name": "first-express-app",

"description": "a fine piece of express art",

Page 26: NodeJS

"version": "0.0.1",

"dependencies": {

"express": "3.x"

}

}

Once the package.json file is updated you'll need to run the npm installation.

npm install

The second method:

This becomes useful if you've already got a package.json file. You can use a lesser

known option on npm install to automatically update your package.json - the save

option.

npm install express –save

The project directory will now have a node_modules folder and inside it will be an

express folder. Your application is now setup to start building.

First Application

To get rolling let's build a very simple application to get familiar with the syntax of

Express. This means creating a main file, in this case app.js.

The start of the file needs to include the express module using a require statement.

Once this is included you can invoke it as a function which will return an Express server

instance. This application instance will allow you to configure and add routes.

var express = require('express');

var app = express();

The next step is to add a route. This is a url that can be retrieved in the application. You

build a route by calling app.METHOD where METHOD is an acceptable HTTP method

like "get". The route is passed the url that will be accessed, such as '/' or the site root.

The second parameter to a route is a callback to call when the url is retrieved.

Page 27: NodeJS

The route callback takes in a req (request) and res (response) which are modified

versions of the objects passed to the core request event. Express adds functionality to

both objects but for this exercise we'll concentrate on the response object.

With the response object the following code will do two things. It will set the content

type header (Content-Type) using the res.type function. A text response will be sent

back using res.send which will automatically set the content length header (Content-

Length).

var express = require('express');

var app = express();

app.get('/', function(req, res) {

res.type('text/plain');

res.send('i am a beautiful butterfly');

});

The final thing we need to do in this simple example is have the app listen for incoming

requests. This is done using the aptly named listen function. This function will take any

valid parameters that you can pass in to the regular http server. In order to make it easy

to change the port and support deploying to platforms like Modulus the port will be set

to process.env.PORT or 4730 (a random port I chose). The process.env.PORT means if

the PORT environment variable is passed in it will use it. This wraps up the basic app.

first.js

var express = require('express');

var app = express();

app.get('/', function(req, res) {

res.type('text/plain'); // set content-type

res.send('i am a beautiful butterfly'); // send text response

});

Page 28: NodeJS

app.listen(process.env.PORT || 4730);

You can test this by running the file using:

node app.js

Then you may go to http://localhost:4730 in your browser and if all went well you'll see

'i am a beautiful butterfly'.

Basic REST API

Now that we have a very basic express application we can dive into a more complex

application.

REST APIs are made up of four method types, GET, PUT, POST, and DELETE and with

Express we can easily do them all. For the rest of this article we're going to build a

simple API that allows you to get and save quotes.

To get started we'll start with a basic Express application that just has an array of quotes.

Each quote is an object with the author and text.

quote.js

var express = require('express');

var app = express();

var quotes = [

{ author : 'Audrey Hepburn', text : "Nothing is impossible, the word itself

says 'I'm possible'!"},

{ author : 'Walt Disney', text : "You may not realize it when it happens, b

ut a kick in the teeth may be the best thing in the world for you"},

{ author : 'Unknown', text : "Even the greatest was once a beginner. Don't

be afraid to take that first step."},

{ author : 'Neale Donald Walsch', text : "You are afraid to die, and you're

afraid to live. What a way to exist."}

];

app.listen(process.env.PORT || 3412);

Page 29: NodeJS

Now you'll notice that this doesn't really do anything. So let's add a route to return all of

the quotes in our array. Now, this is going to be really easy. We're going to take

advantage of a helper function on the response object, to send a json object.

app.get('/', function(req, res) {

res.json(quotes);

});

Let's add the ability to retrieve a random quote. This, again, shouldn't be hard addition.

We'll add a new route '/quote/random'; then we'll calculate a random index, grab the

quote, and return it.

app.get('/quote/random', function(req, res) {

var id = Math.floor(Math.random() * quotes.length);

var q = quotes[id];

res.json(q);

});

The next thing we'll add in there is the ability to grab a single quote. The way you do

this is by adding a ": param" to the route, so the route will look like "/quote/:id" and the

id will be available using req.params.

app.get('/quote/:id', function(req, res) {

if(quotes.length <= req.params.id || req.params.id < 0) {

res.statusCode = 404;

return res.send('Error 404: No quote found');

}

var q = quotes[req.params.id];

res.json(q);

});

In the above the code you can see that we first check to make sure that the id requested

is in the range of quotes we have. If no then we return a 404 error, meaning that the

Page 30: NodeJS

quote wasn't found. In theory we'd probably return a nice error object in this case. If the

request is good then we return the result found based on the id.

One item to note is that since we have "/quote/random" and "/quote/:id" we have to

put the random route first. Why you ask? Well, this is because routes are checked in

order and if it was the other way around "random" would be treated like an id.

So, I'm guessing you'll want to be able to dynamically add quotes to the array. This will

be done using a POST method to the API, this is done using app.post. The POST should

have a JSON object for the new quote.

In order to get the body from a POST in express we have to add a piece of middleware

to our application. This is done using bodyParser middleware. Body parser will pretty

much do what it sounds like - parse the body of the request and then it sets the body

property on the request object.

app.use(express.bodyParser());

The above should be added to the top of the application before we add any routes.

app.post('/quote', function(req, res) {

if(!req.body.hasOwnProperty('author') ||

!req.body.hasOwnProperty('text')) {

res.statusCode = 400;

return res.send('Error 400: Post syntax incorrect.');

}

var newQuote = {

author : req.body.author,

text : req.body.text

};

quotes.push(newQuote);

Page 31: NodeJS

res.json(true);

});

At the beginning of our route function we check to make sure the body has both the

"author" and "text" properties. If they don't exist then we return an error. If the request

is fine then we add it to our quotes and push back a true response.

The last thing thing we'll add is the ability to delete a response. This will be achieved

using the DELETE method.

app.delete('/quote/:id', function(req, res) {

if(quotes.length <= req.params.id) {

res.statusCode = 404;

return res.send('Error 404: No quote found');

}

quotes.splice(req.params.id, 1);

res.json(true);

});

The above function starts by checking the length of our quotes to make sure we don't

try to delete something that isn't there. If no error we splice the array to remove the

quote and return true to the client.

Express application generator Use the application generator tool, express, to quickly create a application skeleton.

Install it with the following command

$ npm install express-generator –g

Display the command options with the -h option:

$ express -h

Page 32: NodeJS

Usage: express [options] [dir]

Options:

-h, --help output usage information

-V, --version output the version number

-e, --ejs add ejs engine support (defaults to jade)

--hbs add handlebars engine support

-H, --hogan add hogan.js engine support

-c, --css <engine> add stylesheet <engine> support (less|stylus|compass)

(defaults to plain css)

-f, --force force on non-empty directory

Note: If you are getting some error like this 'express' is not recognized as an internal or

external command, operable program or batch file, add

c:\Users\<youruser>\AppData\Roaming\npm to your path

For example, the following creates an Express app named myapp in the current working

directory.

$ express myapp

create : myapp

create : myapp/package.json

create : myapp/app.js

create : myapp/public

create : myapp/public/javascripts

create : myapp/public/images

create : myapp/routes

create : myapp/routes/index.js

Page 33: NodeJS

create : myapp/routes/users.js

create : myapp/public/stylesheets

create : myapp/public/stylesheets/style.css

create : myapp/views

create : myapp/views/index.jade

create : myapp/views/layout.jade

create : myapp/views/error.jade

create : myapp/bin

create : myapp/bin/www

install dependencies:

$ cd myapp && npm install

run the app:

$ DEBUG=myapp ./bin/www

On Windows, use the following command to run the app.

set DEBUG=myapp & node .\bin\www

The generated app directory structure looks like the following.

.

├── app.js

├── bin

│ └── www

├── package.json

├── public

│ ├── images

│ ├── javascripts

│ └── stylesheets

Page 34: NodeJS

│ └── style.css

├── routes

│ ├── index.js

│ └── users.js

└── views

├── error.jade

├── index.jade

└── layout.jade

7 directories, 9 files

Taking Baby Steps with Node.js –

Debugging with node-inspector Writing unit tests for your code drastically reduces the amount of debugging. This is the

case for practically any programming language that you work in. But when issues hit the

app, having a debugger with some decent features at your disposal is a must. However

Node.js doesn’t come with a debugger out of the box. Thankfully there are a couple of

debuggers out there like ndb, node-debug and node-inspector.

Installing node-inspector is actually pretty easy when you have npm installed. Just issue

the following command:

npm install node-inspector

Now we can startup node-inspector

node-inspector &

Which shows the following output if all goes well:

visit http://127.0.0.1:8080 to start debugging

Page 35: NodeJS

Now that we have node-inspector running, we can start debugging our node.js

application in another console:

node --debug server.js

Which outputs the port on which the debugger is listening.

debugger listening on port 5858

Now you can open Chrome and point it to the following URL:

http://127.0.0.1:8080/

If all goes well, then we’ll get to see some JavaScript source code:

Note that you’ll have to use Chrome or another WebKit based browser for opening

node-inspector.

You can then select the JavaScript source file that contains the code you wish to debug

and add breakpoints like you would normally do in an IDE like Visual Studio. Now we

can start using our application until we hit a breakpoint.

Page 36: NodeJS

On the right of the page we can add watch expressions, look at the call stack and the

current values of the scope variables. In the code window we have the usual suspects

like ―Step over‖, ―Step into next function‖ and ―Step out of current function‖. We can

even do live editing and all of this right in the browser! Tooltips also work as expected.

Page 37: NodeJS

Another nice feature is the console window that can be shown/hidden below or taking

over the entire window by clicking the menu button at the top of the page.

Page 38: NodeJS

Using node-inspector while developing Node.js applications can really save you a lot of

grief.

Summarizing NodeJS Node is a wrapper around the high-performance V8 JavaScript runtime from the Google

Chrome browser. Node tunes V8 to work better in contexts other than the browser,

mostly by providing additional APIs that are optimized for specific use cases. For

example, in a server context, manipulation of binary data is often necessary. This is

poorly supported by the JavaScript language and, as a result, V8. Node’s Buffer class

provides easy manipulation of binary data. Thus, Node doesn’t just provide direct access

to the V8 JavaScript runtime. It also makes JavaScript more useful for the contexts in

which people use Node. V8 itself uses some of the newest techniques in compiler

technology. This often allows code written in a high-level language such as JavaScript to

perform similarly to code written in a lower-level language, such as C, with a fraction of

the development cost. This focus on performance is a key aspect of Node. JavaScript is

an event-driven language, and Node uses this to its advantage to produce highly

scalable servers. Using architecture called an event loop, Node makes programming

highly scalable servers both easy and safe. There are various strategies that are used to

make servers performant. Node has chosen an architecture that performs very well but

also reduces the complexity for the application developer. This is an extremely

important feature. Programming concurrency is hard and fraught with danger. Node

sidesteps this challenge while still offering impressive performance. To support the

event-loop approach, Node supplies a set of ―nonblocking‖ libraries. In essence, these

are interfaces to things such as the filesystem or databases, which operate in an event-

driven way. When you make a request to the filesystem, rather than requiring Node to

wait for the hard drive to spin up and retrieve the file, the nonblocking interface simply

notifies Node when it has access, in the same way that web browsers notify your code

about an onclick event. This model simplifies access to slow resources in a scalable way

that is intuitive to JavaScript programmers and easy to learn for everyone else.