Tuesday, March 21, 2017

Quick Tutorials on NodeJS

Node.js

1. Node.js is a very powerful JavaScript-based framework/platform built on Google Chrome's JavaScript V8 Engine.
2. It is used to develop I/O intensive web applications like video streaming sites, single-page applications, and other web applications.
3. Node.js is a server side platform built on Google Chrome's JavaScript Engine (V8 Engine).
4. Node.js is a platform built on Chrome's JavaScript runtime for easily building fast and scalable network applications.
5. 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.

**Node.js = Runtime Environment + JavaScript Library**

##Features of Node.js

1. Asynchronous and Event Driven
2. Very Fast
3. Single Threaded but Highly Scalable
4. No Buffering

##Concepts

![alt tag](file:///Users/vkumar/_dev/node-master/img/nodejs_concepts.jpg)

##Where to Use Node.js?

* I/O bound Applications
* Data Streaming Applications
* Data Intensive Real time Applications (DIRT)
* JSON APIs based Applications
* Single Page Applications

##Node.js - First Application

A Node.js application consists of following three important parts −

1. Import required modules
2. Create server
3. Read request and return response

##Node.js - REPL (Read Eval Print Loop) Terminal

* Read - Reads user's input, parse the input into JavaScript data-structure and stores in memory.
* Eval - Takes and evaluates the data structure
* Print - Prints the result
* Loop - Loops the above command until user press ctrl-c twice.

##REPL Commands

* ctrl + c - terminate the current command.
* ctrl + c twice - terminate the Node REPL.
* ctrl + d - terminate the Node REPL.
* Up/Down Keys - see command history and modify previous commands.
* tab Keys - list of current commands.
* .help - list of all commands.
* .break - exit from multiline expression.
* .clear - exit from multiline expression
* .save filename - save current Node REPL session to a file.
* .load filename - load file content in current Node REPL session.

##Node.js - npm

Node Package Manager (npm) provides following two main functionalities:

1. Online repositories for node.js packages/modules which are searchable on search.nodejs.org
2. Command line utility to install Node.js packages, do version management and dependency management of Node.js packages.

##Attributes of Package.json

1. name - name of the package
2. version - version of the package
3. description - description of the package
4. homepage - homepage of the package
5. author - author of the package
6. contributors - name of the contributors to the package
7. dependencies - list of dependencies. npm automatically installs all the dependencies mentioned here in the node_module folder of the package.
8. repository - repository type and url of the package
9. main - entry point of the package
10. keywords - keywords

##npm commands

* Content - $ npm ls
* Uninstalling a module - $ npm uninstall express
* Updating a module - $ npm update express
* Search - $ npm search express
*Create a module - $ npm init, $ npm adduser, $ npm publish


##Node.js - Callbacks Concept

* Callback is an asynchronous equivalent for a function.
* A callback function is called at the completion of a given task.
* Node makes heavy use of callbacks.
* All APIs of Node are written is such a way that they supports callbacks.

##Node.js - Event Loop

* Node js is a single threaded application but it support concurrency via concept of event and callbacks.
* As every API of Node js are asynchronous and being a single thread, it uses async function calls to maintain the concurrency.
* Node uses observer pattern.
* Node thread keeps an event loop and whenever any task get completed, it fires the corresponding event which signals the event listener function to get executed.

###Observer Pattern
* Observer pattern is used when there is one-to-many relationship.
* Its depenedent objects are to be notified automatically.
* Observer pattern falls under behavioral pattern category.

###Event Driven Programming

* Node.js uses events heavily and it is also one of the reasons why Node.js is pretty fast compared to other similar technologies.
* As soon as Node starts its server, it simply initiates its variables, delcares functions and then simply waits for event to occur.
* In an event-driven application, there is generally a main loop that listens for events, and then triggers a callback function when one of those events is detected.

![alt tag](file:///Users/vkumar/_dev/node-master/img/event_loop.jpg)

// Import events module
var events = require('events');
// Create an eventEmitter object
var eventEmitter = new events.EventEmitter();

// Create an event handler as follows
var connectHandler = function connected() {
  console.log('connection succesful.');

  // Fire the data_received event
  eventEmitter.emit('data_received');
}

// Bind the connection event with the handler
eventEmitter.on('connection', connectHandler);

// Bind the data_received event with the anonymous function
eventEmitter.on('data_received', function(){
  console.log('data received succesfully.');
});

// Fire the connection event
eventEmitter.emit('connection');

console.log("Program Ended.");

$ mnode main.js

connection succesful.
**data received succesfully.**
Program Ended.

##Node.js - Event Emitter

* All objects which emit events are instances of events.EventEmitter.
* Many objects in Node emit events for example a net.Server emits an event each time a peer connects to it
* A fs.readStream emits an event when the file is opened.

###EventEmitter Class

* EventEmitter class lies in events module. It is accessibly via following syntax:

// Import events module
var events = require('events');
// Create an eventEmitter object
var eventEmitter = new events.EventEmitter();

* When an EventEmitter instance faces any error, it emits an 'error' event.
* When new listener is added, 'newListener' event is fired and when a listener is removed, 'removeListener' event is fired.
* EventEmitter provides multiple properties like on and emit. on property is used to bind a function with the event and emit is used to fire an event.

###Methods

* addListener(event, listener)
* on(event, listener)
* once(event, listener) - Adds a one time listener for the event
* removeListener(event, listener)
* removeAllListeners([event])
* setMaxListeners(n) - By default EventEmitters will print a warning if more than 10 listeners are added for a particular event.
* listeners(event) - Returns an array of listeners for the specified event.
* emit(event, [arg1], [arg2], [...]) - Execute each of the listeners in order with the supplied arguments.
* listenerCount(emitter, event) - Return the number of listeners for a given event.

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

// listener #1
var listner1 = function listner1() {
  console.log('listner1 executed.');
}

// listener #2
var listner2 = function listner2() {
 console.log('listner2 executed.');
}

// Bind the connection event with the listner1 function
eventEmitter.addListener('connection', listner1);

// Bind the connection event with the listner2 function
eventEmitter.on('connection', listner2);

var eventListeners = require('events').EventEmitter.listenerCount(eventEmitter,'connection');
console.log(eventListeners + " Listner(s) listening to connection event");

// Fire the connection event
eventEmitter.emit('connection');

// Remove the binding of listner1 function
eventEmitter.removeListener('connection', listner1);
console.log("Listner1 will not listen now.");

// Fire the connection event
eventEmitter.emit('connection');

eventListeners = require('events').EventEmitter.listenerCount(eventEmitter,'connection');
console.log(eventListeners + " Listner(s) listening to connection event");

console.log("Program Ended.");

##Node.js - Buffers

* Pure JavaScript is Unicode friendly but not nice to binary data.
* When dealing with TCP streams or the file system, it's necessary to handle octet streams.
* Node provides Buffer class which provides instances to store raw data similar to an array of integers but corresponds to a raw memory allocation outside the V8 heap.
* Buffer class is a global class and can be accessed in application without importing buffer module.

###Creating Buffers

var buf = new Buffer(10); //an uninitiated Buffer of 10 octets
var buf = new Buffer([10, 20, 30, 40, 50]); //a Buffer from a given array
var buf = new Buffer("Simply Easy Learning", "utf-8"); //a Buffer from a given string and optionally encoding type

###Writing to Buffers

buf.write(string[, offset][, length][, encoding]) //method to write into a Node Buffer

###Reading from Buffers

buf.toString([encoding][, start][, end]) //read data from a Node Buffer

###Convert Buffer to JSON

buf.toJSON() //convert a Node Buffer into JSON object

###Concatenate Buffers

Buffer.concat(list[, totalLength]) //concatenate Node buffers to a single Node Buffer

###Compare Buffers

buf.compare(otherBuffer); //compare two Node buffers

###Copy Buffer

buf.copy(targetBuffer[, targetStart][, sourceStart][, sourceEnd]) //copy a node buffer

###Slice Buffer

buf.slice([start][, end]) //a sub-buffer of a node buffer

###Buffer Length

a node buffer in bytes //a node buffer in bytes

##Node.js - Streams

* Streams are objects that let us read data from a source or write data to a destination in continous fashion.
* In Node.js, there are four types of streams.

1. Readable - Stream which is used for read operation.
2. Writable - Stream which is used for write operation.
3. Duplex - Stream which can be used for both read and write operation.
4. Transform - A type of duplex stream where the output is computed based on input.

Each type of Stream is an EventEmitter instance and throws several events at different instance of times. For example, some of the commonly used events are:

* data - This event is fired when there is data is available to read.
* end - This event is fired when there is no more data to read.
* error - This event is fired when there is any error receiving or writing data.
* finish - This event is fired when all data has been flushed to underlying system.

###Reading from stream

var fs = require("fs");
var data = '';

// Create a readable stream
var readerStream = fs.createReadStream('input.txt');

// Set the encoding to be utf8.
readerStream.setEncoding('UTF8');

// Handle stream events --> data, end, and error
readerStream.on('data', function(chunk) {
  data += chunk;
});

readerStream.on('end',function(){
  console.log(data);
});

readerStream.on('error', function(err){
  console.log(err.stack);
});

console.log("Program Ended");

###Writing to stream

var fs = require("fs");
var data = 'Simply Easy Learning';

// Create a writable stream
var writerStream = fs.createWriteStream('output.txt');

// Write the data to stream with encoding to be utf8
writerStream.write(data,'UTF8');

// Mark the end of file
writerStream.end();

// Handle stream events --> finish, and error
writerStream.on('finish', function() {
   console.log("Write completed.");
});

writerStream.on('error', function(err){
  console.log(err.stack);
});

console.log("Program Ended");

###Piping streams

var fs = require("fs");

// Create a readable stream
var readerStream = fs.createReadStream('input.txt');

// Create a writable stream
var writerStream = fs.createWriteStream('output.txt');

// Pipe the read and write operations
// read input.txt and write data to output.txt
readerStream.pipe(writerStream);

console.log("Program Ended");

###Chaining streams

var fs = require("fs");
var zlib = require('zlib');

// Compress the file input.txt to input.txt.gz
fs.createReadStream('input.txt')
 .pipe(zlib.createGzip())
 .pipe(fs.createWriteStream('input.txt.gz'));

console.log("File Compressed.");

##Node.js - File System

Node implements File I/O using simple wrappers around standard POSIX functions.

###Synchronous vs Asynchronous

* Every method in fs module have synchronous as well as asynchronous form.
* Asynchronous methods takes a last parameter as completion function callback and first parameter of the callback function is error.
* It is preferred to use asynchronous method instead of synchronous method as former never block the program execution where as the second one does.

###Open a File

fs.open(path, flags[, mode], callback)

###Get File information

fs.stat(path, callback)

###Writing File

fs.writeFile(filename, data[, options], callback)

###Reading File

fs.read(fd, buffer, offset, length, position, callback)

###Closing File

fs.close(fd, callback)

###Truncate File

fs.ftruncate(fd, len, callback)

###Delete File

fs.unlink(path, callback)

###Create Directory

fs.mkdir(path[, mode], callback)

###Read Directory

fs.readdir(path, callback)

###Remove Directory

fs.rmdir(path, callback)


##Node.js - Global Objects

* Node.js global objects are global in nature and they are available in all modules.
* We do not need to include these objects in our application, rather we can use them directly.
* These objects are modules, functions, strings and object itself as explained below.

1. __filename - represents the filename of the code being executed.
2. __dirname - represents the name of the directory
3. setTimeout(cb, ms) - global function is used to run callback
4. clearTimeout(t) - global function is used to stop a timer
5. setInterval(cb, ms) - global function is used to run callback

###Global Objects

* Console - Used to print information on stdout and stderr.
* Process - Used to get information on current process.


##Node.js - Utility Modules

1. OS Module - Provides basic operating-system related utility functions.
2. Path Module - Provides utilities for handling and transforming file paths.
3. Net Module - Provides both servers and clients as streams. Acts as a network wrapper.
4. DNS Module - Provides functions to do actual DNS lookup as well as to use underlying operating system name resolution functionalities.
5. Domain Module - Provides way to handle multiple different I/O operations as a single group.

##Node.js - Web Module

* Web Server is a software application which handles HTTP requests sent by the HTTP client, like web browsers, and returns web pages in response to the clients.
* Web servers usually delivers html documents along with images, style sheets and scripts.
* Apache web server is one of the most commonly used web server. It is an open source project.

###Web Application Architecture

![alt tag](file:///Users/vkumar/_dev/node-master/img/web_architecture.jpg)

###Creating Web Server using Node

* Node.js provides http module which can be used to create either HTTP client of server.
* Following is a bare minimum structure of HTTP server which listens at 8081 port.

1. Create a js file named server.js:

var http = require('http');
var fs = require('fs');
var url = require('url');

// Create a server
http.createServer( function (request, response) {
  // Parse the request containing file name
  var pathname = url.parse(request.url).pathname;
 
  // Print the name of the file for which request is made.
  console.log("Request for " + pathname + " received.");
 
  // Read the requested file content from file system
  fs.readFile(pathname.substr(1), function (err, data) {
     if (err) {
        console.log(err);
        // HTTP Status: 404 : NOT FOUND
        // Content Type: text/plain
        response.writeHead(404, {'Content-Type': 'text/html'});
     }else{
        //Page found
        // HTTP Status: 200 : OK
        // Content Type: text/plain
        response.writeHead(200, {'Content-Type': 'text/html'});
       
        // Write the content of the file to response body
        response.write(data.toString());
     }
     // Send the response body
     response.end();
  });  
}).listen(8081);

// Console will print the message

2. Create index.htm file

<html>
<head>
<title>Sample Page</title>
</head>
<body>
Hello World!
</body>
</html>

3. Run server.js

$ node server.js

4. Navigate to the browser

http://127.0.0.1:8081/

###Creating Web client using Node

A web client can be created using http module. Let's check the following example.

1. Create a js file named client.js:

var http = require('http');

// Options to be used by request
var options = {
  host: 'localhost',
  port: '8081',
  path: '/index.htm'
};

// Callback function is used to deal with response
var callback = function(response){
  // Continuously update stream with data
  var body = '';
  response.on('data', function(data) {
     body += data;
  });
 
  response.on('end', function() {
     // Data received completely.
     console.log(body);
  });
}
// Make a request to the server
var req = http.request(options, callback);
req.end();

2. Run client.js

$ node client.js

3. Verify the Output

<html>
<head>
<title>Sample Page</title>
</head>
<body>
Hello World!
</body>
</html>

4. Verify the Output at server end.


##Node.js - Express Framework

Express is a minimal and flexible Node.js web application framework that provides a robust set of features to develop web and mobile applications.
It facilitates a rapid development of Node based Web applications. Following are some of the core features of Express framework:

* Allows to set up middlewares to respond to HTTP Requests.
* Defines a routing table which is used to perform different action based on HTTP Method and URL.
* Allows to dynamically render HTML Pages based on passing arguments to templates.

$ npm install express --save
$ npm install body-parser --save
$ npm install cookie-parser --save
$ npm install multer --save

There are following important modules which you should install along with express:

* body-parser - This is a node.js middleware for handling JSON, Raw, Text and URL encoded form data.
* cookie-parser - Parse Cookie header and populate req.cookies with an object keyed by the cookie names.
* multer - This is a node.js middleware for handling multipart/form-data.


###Hello world Example

var express = require('express');
var app = express();

app.get('/', function (req, res) {
  res.send('Hello World');
})

var server = app.listen(8081, function () {

 var host = server.address().address
 var port = server.address().port

 console.log("Example app listening at http://%s:%s", host, port)
})


###Request & Response

Express application makes use of a callback function whose parameters are request and response objects.

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

* Request Object - The request object represents the HTTP request and has properties for the request query string, parameters, body, HTTP headers, and so on.

* Response Object - The response object represents the HTTP response that an Express app sends when it gets an HTTP request.

###Basic Routing

* We have seen a basic application which serves HTTP request for the homepage.
* Routing refers to determining how an application responds to a client request to a particular endpoint, which is a URI (or path) and a specific HTTP request method (GET, POST, and so on).

###Serving Static Files

* Express provides a built-in middleware express.static to serve static files, such as images, CSS, JavaScript etc.
* You simply needs to pass the name of the directory where you keep your static assets, to the express.static middleware to start serving the files directly.

app.use(express.static('public'));

###Cookies Management

Can send cookies to Node.js server which can handle the using the following middleware option.

var express      = require('express')
var cookieParser = require('cookie-parser')

var app = express()
app.use(cookieParser())

app.get('/', function(req, res) {
 console.log("Cookies: ", req.cookies)
})

app.listen(8081)

##Node.js - RESTful API


1. REST stands for REpresentational State Transfer.
2. REST is web standards based architecture and uses HTTP Protocol.
3. It revolves around resource where every component is a resource and a resource is accessed by a common interface using HTTP standard methods.
4. A REST Server simply provides access to resources and REST client accesses and modifies the resources using HTTP protocol.
5. REST uses various representation to represent a resource like text, JSON, XML but JSON is the most popular one.


###HTTP methods

1. GET - This is used to provide a read only access to a resource.
2. POST - This is used to update a existing resource or create a new resource.
3. PUT - This is used to create a new resource.
4. DELETE - This is used to remove a resource.

###RESTful Web Services

* A web service is a collection of open protocols and standards used for exchanging data between applications or systems.
* Web services based on REST Architecture are known as RESTful web services.
* These webservices uses HTTP methods to implement the concept of REST architecture.
* A RESTful web service usually defines a URI, Uniform Resource Identifier a service, which provides resource representation such as JSON and set of HTTP Methods.


##Node.js - Scaling Application

* As Node.js runs in a single thread mode but it uses an event-driven paradigm to handle concurrency.
* It also facilitates creation of child processes to leverage parallel processing on multi-core cpu based systems.
* Child processes always have three streams child.stdin, child.stdout, and child.stderr which may be shared with the stdio streams of the parent process.
* Node provides child_process module which has following three major ways to create child process.

1. exec - child_process.exec method runs a command in a shell/console and buffers the output.
2. spawn - child_process.spawn launches a new process with a given command
3. fork - The child_process.fork method is a special case of the spawn() to create child processes.

child_process.exec(command[, options], callback)
child_process.spawn(command[, args][, options])
child_process.fork(modulePath[, args][, options])


##Node.js - Packaging

* Node.js code is open and ready to be copied like any other Javascript code.
* But now you can compile your Node.js code into binary and distribute it.

$ wget https://github.com/jxcore/jxcore/archive/master.zip

$ unzip master.zip
$ cd jxcore-master
$ ./configure
$ make
$ make install

$ export PATH=$PATH:/usr/bin

$ jx --version
v0.10.32

$ jx package index.js index

$ node index.js command_line_arguments

$ jx index.jx command_line_arguments