COMPUTER 10: Lesson 7 - File Storage and Online Collaboration
Introduction to Node js
1. A K S H A Y M A T H U R
@AKSHAYMATHU
Getting Started with
2. Ground Rules
@akshaymathu
2
Post on FB and Tweet now
Disturb Everyone during the
session
Not by phone rings
Not by local talks
By more information and
questions
3. Let’s Know Each Other
@akshaymathu
3
Do you code?
OS?
Node?
JavaScript, JSON?
Web Development?
CoffeeScript
Other Programing Language?
Why are you attending?
4. Akshay Mathur
@akshaymathu
4
Founding Team Member of
ShopSocially (Enabling “social” for retailers)
AirTight Neworks (Global leader of WIPS)
15+ years in IT industry
Currently Principal Architect at ShopSocially
Mostly worked with Startups
From Conceptualization to Stabilization
At different functions i.e. development, testing, release
With multiple technologies
5. JavaScript
@akshaymathu
5
Born in 1995 at Netscape
Not at all related to Java
Syntax influenced by C
Interpreted ECMA scripting language
Dynamically typed
Object Oriented as well as Functional
Prototype based
6. Typical Usage
@akshaymathu
6
Web programing
Client side
Web pages
Browser plugins
Server side
SSJS (not in use)
NodeJS
PDF documents
Desktop Widgets
MongoDB
7. NodeJS
JavaScript Runtime at command line
Allows us to write JS programs outside browser
Built on V8 JS engine
V8 is open source JS engine developed by Google
It also powers Google Chrome
Written in C++
Compiles JS code to native before execution
@akshaymathu
7
8. Good for
For IO heavy apps
Web socket (chat) server
Real time collaborative editor
Fast file uploads
Ad server
Any other real time data app (e.g. streaming server)
Crawler
Asynchronous chaining of tasks
NOT good for CPU heavy apps
Weather prediction
May not be good for big projects
@akshaymathu
8
9. NodeJS is NOT
A web framework
Provides tools to create a web server
Multi threaded
Is Single threaded, event driven, asynchronous, non-blocking
For beginners
Needs programing at very low level
You start with writing a web server
@akshaymathu
9
10. Possible Issues
@akshaymathu
10
Can not utilize multicore processer because of single
thread
Managing multiple processes from outside may be even bigger
problem
Any CPU intensive task delays all the requests
Requires constant attention (non-traditional thinking)
for not having blocking code
In case of big products the code/logic gets distributed in
multiple callback functions
If data needs to collected from different places and
correlated, synchronizing all callbacks becomes tough
Garbage collection may also be an issue
11. S I N G L E T H R E A D E D
E V E N T D R I V E N
A S Y N C H R O N O U S
N O N - B L O C K I N G
What Jargons Mean
12. Single Threaded
New Node process does not start for every request
Only one code executes at a time
Everything else remains in the queue
No worry about different portions of code accessing the same
data structures at the same time
Delay at one place delays everything after that
Can not take advantage of multi-core CPU
Then how NodeJS is fast?
@akshaymathu
12
13. Non-blocking
There is only one process that is executing
If the process waits for something to complete, everything else
gets delayed
So the code has to be structured in a way that wait
for IO happens outside the main execution
@akshaymathu
13
14. Blocking Vs. Non-blocking
@akshaymathu
14
var a = db.query('SELECT * from huge_table’);
console.log('result a:’, a);
console.log(‘Doing something else’);
Blocking I/O
Non-Blocking I/O
db.query('SELECT * from huge_table’, function(res) {
console.log('result a:’, res);
});
console.log(‘Doing something else’);
15. Asynchronous
Not all code is executed in the same order it is
written
Node (and you) divide the code into small pieces and
fire them in parallel
Typically the code announces its state of execution
(or completion) via events
@akshaymathu
15
16. Event Driven
A code block gets into the queue of execution when
an event happens
It gets executed on its turn
Anyone can raise (or listen to) an event
System
Some library (module)
Your code
You have the choice (and ways) to attach a code
block to an event
Also known as event callbacks
@akshaymathu
16
18. ‘King and Servants’ Analogy… by Felix Geisendörfer
everything runs in parallel, except your code. To understand that,
imagine your code is the king, and node is his army of servants.
The day starts by one servant waking up the king and asking him if he
needs anything. The king gives the servant a list of tasks and goes back
to sleep a little longer. The servant now distributes those tasks among
his colleagues and they get to work.
Once a servant finishes a task, he lines up outside the kings quarter to
report. The king lets one servant in at a time, and listens to things he
reports. Sometimes the king will give the servant more tasks on the
way out.
Life is good, for the king's servants carry out all of his tasks in parallel,
but only report with one result at a time, so the king can focus.
@akshaymathu
18
20. D O T H E Y O C C U R O N S E R V E R A S W E L L ?
Events
21. Events we know…
@akshaymathu
21
The event familiar to us are
Click
Focus
Blur
Hover
These events are raised when user interacts with
DOM elements
But the DOM is not being rendered in NodeJS
Then what events are we talking about in NodeJS?
22. Node Events
@akshaymathu
22
The most common event that a web server uses is
request
Raised when a web request (url) hits the server
Other events:
When chunk of multipart data (file) is received
When all chunks of file are received
When system finishes reading a file
When data set is returned by a database query
…
You can define your own events using event emitter
23. Let’s Revise: JS Function Facts
@akshaymathu
23
Function is a block of a code that gets executed when
called
JS function may not have a name
Anonymous functions can be used
JS function accept any data type as argument
Function is a valid data type in JS
A function can be assigned to a variable
A function can be passed as an argument to another
function
A function can be defined inside another function
24. Event Callback
@akshaymathu
24
Because the system is single threaded
And we do not want to block it for I/O
We use asynchronous functions for getting work done
We depend on the events to tell when some work is
finished
And we want some code to execute when the event occurs
Asynchronous functions take a function as an
additional argument and call the function when the
event occurs
This function is known as callback function
25. Callback in Action
@akshaymathu
25
callback = function(res) {
console.log('result a:’, res);
};
db.query('SELECT * from huge_table’, callback);
Or
db.query('SELECT * from huge_table’, function(res) {
console.log('result a:’, res);
});
27. N O T H I N G B U T L I B R A R I E S
Node Modules
28. Available Modules
@akshaymathu
28
Modules are nothing but collections of useful
functions
Otherwise we call them libraries
Built-in modules come with NodeJS installation
http, tcp, url, dns, buffer, udp etc.
People create more modules, package and publish
them for others to use
less, coffee, express etc.
1000+ modules are available via npm
You can write your own custom module for
organizing your code better
29. Creating Custom Module
@akshaymathu
29
Write some useful code in a file
Some function(s) achieving a goal
Decide what should be available outside for others to
use
Public API of your module
Make the APIs available outside using exports object
my_api = function(){…};
exports.myApi = my_api;
30. Using Modules
@akshaymathu
30
‘require’ functions loads a module
Whatever has been exported becomes available with
‘require’ and can be assigned to a variable for later
use
var http = require(‘http’);
var custom = require(‘./my_api’);
custom.myApi();
32. A S I M P L E W E B S E R V E R
@akshaymathu
32
Let’s Program
33. Hello World
@akshaymathu
33
Just one line is needed to write to STDOUT
console.log(‘Hello World’)
Running the file with Node just works
node hello_world.js
35. Improving the Server
@akshaymathu
35
Running this server with Node starts the server
node server.js
The server always returns same string
Try any url, browser always says “Hello World”
Actually the server should respond content based on
URL
It should route the request to proper handler
Handler should return proper content
36. Organizing Code
@akshaymathu
36
Rather than writing everything in single file, it is a
good idea to divide the code into logical modules
Main startup file: index.js
Web server: server.js
URL Router: routes.js
Request Handler: requestHandlers.js
…
More files and directories will come as the code
grows
37. Initial Server Module
@akshaymathu
37
var http = require("http");
function start() {
function onRequest(request, response){
console.log("Request received.");
response.writeHead(200,
{"Content-Type": "text/plain"});
response.write("Hello World");
response.end();
}
http.createServer(onRequest).listen(8888);
console.log("Server has started.");
}
exports.start = start;
38. Initial Startup File
@akshaymathu
38
As server became a module and exposes a start
function, we need to
load server module
Call start function to start the server
var server = require("./server");
server.start();
Running the main file with now starts the server
node index.js
But it still returns ‘Hello world’ for all URLs
39. Let’s Revise: Parts of URL
https://sub.domain.com:8086/a/folder/file.html?key
=val&key=val2#some_place
Protocol
Sub-domain, Domain and TLD
Port
Path
File
Query string
Fragment
@akshaymathu
39
40. Server – Router Interaction
@akshaymathu
40
For routing the requests based on URL, the router
must know pathname of the requested URL
The URL can be read from the ‘request’ object available in
server module
So what should we pass to the router?
Request object
URL (Extract URL from request in server)
Pathname (Extract and parse URL in server)
??
If server need to call router, how router becomes
available to server?
42. Router Aware Server
@akshaymathu
42
var http = require("http");
var url = require("url");
function start(route) {
function onRequest(request, response){
var pathname =
url.parse(request.url).pathname;
route(pathname);
response.writeHead(200, "Content-Type": "text/plain"});
response.write("Hello World");
response.end();
}
http.createServer(onRequest).listen(8888);
}
exports.start = start;
43. Making Router Available to Server
@akshaymathu
43
Router is made available as an argument (dependency) to
server’s ‘start’ function
This is also known as dependency injection
var server = require("./server");
var router = require("./router");
server.start(router.route);
Router module is loaded in startup file and the route
function is passed at the time of starting server
Server then calls route function of the router with the
pathname
44. Adding Request Handlers
@akshaymathu
44
The actual work of creating response for a request
will be done by Request Handlers
We need to add these handlers to the server
The requestHandlers module will consist of a
function corresponding to each expected URL
At some place, we also need mapping between URL
and the request handler function
45. Initial Request Handlers
@akshaymathu
45
function start() {
console.log("Request for 'start’.");
return "Hello Start";
}
function upload() {
console.log("Request for 'upload.");
return "Hello Upload";
}
exports.start = start;
exports.upload = upload;
46. Including Handlers
@akshaymathu
46
var server = require("./server");
var router = require("./router");
var requestHandlers =
require("./requestHandlers");
var handle = {}
handle["/"] = requestHandlers.start;
handle["/start"] = requestHandlers.start;
handle["/upload"] = requestHandlers.upload;
server.start(router.route, handle);
47. Change in Server
@akshaymathu
47
function start(route, handle) {
function onRequest(request, response) {
var pathname =
url.parse(request.url).pathname;
content = route(handle, pathname);
response.writeHead(200, {"Content-Type":
"text/plain"});
response.write(content);
response.end();
}
http.createServer(onRequest).listen(8888);
console.log("Server has started.");
}
exports.start = start;
48. Real Routing
@akshaymathu
48
function route(handle, pathname) {
console.log(”Routing request for " + pathname);
if (typeof handle[pathname] === 'function') {
return handle[pathname]();
} else {
console.log("No request handler found
for " + pathname);
}
}
exports.route = route;
51. What is wrong?
@akshaymathu
51
function start(route, handle) {
function onRequest(request, response) {
var pathname =
url.parse(request.url).pathname;
content = route(handle, pathname);
response.writeHead(200, {"Content-Type": "text/plain"});
response.write(content);
response.end();
}
http.createServer(onRequest).listen(8888);
console.log("Server has started.");
}
exports.start = start;
Blocking
Code
52. What are the problems?
@akshaymathu
52
The way ‘content’ is being collected and being
written to response, it forces to write blocking
synchronous code in handlers
Because handler has to return content when called
If you write asynchronous code in handler, the server
will always return response with no content
Because handler will return nothing and when callback will
return with the content, there will be no one to collect the
output
53. The Right Way
@akshaymathu
53
The content should be written into response object
when the content becomes available
So the response object should be made available to
request handlers
Response object is available in server
Server is not directly calling request handlers
So first, Response object will be passed to router
And then, Router will pass it to request handlers
54. Corrected Server
@akshaymathu
54
var http = require("http");
var url = require("url");
function start(route, handle) {
function onRequest(request, response) {
var pathname =
url.parse(request.url).pathname;
console.log("Request for " + pathname);
route(handle, pathname, response);
}
http.createServer(onRequest).listen(8888);
console.log("Server has started.");
}
exports.start = start;
55. Corrected Router
@akshaymathu
55
function route(handle, pathname, response) {
console.log(”Routing request for " + pathname);
if (typeof handle[pathname] === 'function') {
handle[pathname](response);
} else {
console.log("No handler found for " +
pathname);
response.writeHead(404, {"Content-Type":
"text/plain"});
response.write("404 Not found");
response.end();
}
}
exports.route = route;
56. Corrected Handlers
@akshaymathu
56
function start(response) {
db.query(”select * from huge_table”,
function (error, stdout, stderr) {
response.writeHead(200,
{"Content-Type": "text/plain"});
response.write(stdout);
response.end();
});
}
exports.start = start;
59. Summary
Node will require extra work and different thought
process
But it will pay off for it
Choose Node carefully only for the type of app it is
best suited
You may not need to write code at the lowest level we
discussed here
You may want to choose framework
@akshaymathu
59
60. MVC in Node
Express (Controller)
Mongoose (Model)
Jade (View)
More …
@akshaymathu
60