introduction to node js

Post on 15-Jan-2015

2.527 Views

Category:

Technology

2 Downloads

Preview:

Click to see full reader

DESCRIPTION

Introduction to NodeJS

TRANSCRIPT

AKSHAY MATHUR

@AKSHAYMATHU

Getting Started with

@akshaymathu

2

Ground Rules

Post on FB and Tweet nowDisturb Everyone during

the session Not by phone rings Not by local talks By more information and

questions

@akshaymathu

3

Let’s Know Each Other

Do you code?OS?Node?JavaScript, JSON?Web Development?CoffeeScriptOther Programing Language?Why are you attending?

@akshaymathu

4

Akshay Mathur

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

@akshaymathu

5

JavaScript

Born in 1995 at NetscapeNot at all related to JavaSyntax influenced by CInterpreted ECMA scripting languageDynamically typedObject Oriented as well as FunctionalPrototype based

@akshaymathu

6

Typical Usage

Web programing Client side

Web pages Browser plugins

Server side SSJS (not in use) NodeJS

PDF documentsDesktop WidgetsMongoDB

@akshaymathu

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

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

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

10

Possible Issues

Can not utilize multicore processer because of single thread Managing multiple processes from outside may be even bigger

problemAny CPU intensive task delays all the requestsRequires constant attention (non-traditional thinking)

for not having blocking codeIn case of big products the code/logic gets distributed

in multiple callback functionsIf data needs to collected from different places and

correlated, synchronizing all callbacks becomes toughGarbage collection may also be an issue

SINGLE THREADED EVENT DRIVEN

ASYNCHRONOUSNON-BLOCKING

What Jargons Mean

@akshaymathu

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 timeDelay at one place delays everything after that Can not take advantage of multi-core CPU

Then how NodeJS is fast?

@akshaymathu

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

14

Blocking Vs. Non-blocking

var a = db.query('SELECT * from huge_table’);console.log('result a:’, a);

console.log(‘Doing something else’);

Blocking I/O

Non-Blocking I/Odb.query('SELECT * from huge_table’, function(res) { console.log('result a:’, res);});

console.log(‘Doing something else’);

@akshaymathu

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

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

17

The Event Queue

@akshaymathu

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

DO THEY OCCUR ON SERVER AS WELL?

Events

@akshaymathu

21

Events we know…

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?

@akshaymathu

22

Node Events

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

@akshaymathu

23

Let’s Revise: JS Function Facts

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 argumentFunction is a valid data type in JSA function can be assigned to a variableA function can be passed as an argument to

another functionA function can be defined inside another

function

@akshaymathu

24

Event Callback

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

occursAsynchronous functions take a function as an

additional argument and call the function when the event occurs This function is known as callback function

@akshaymathu

25

Callback in Action

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);});

@akshaymathu 26

NOTHING BUT LIBRARIES

Node Modules

@akshaymathu

28

Available Modules

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

@akshaymathu

29

Creating Custom Module

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;

@akshaymathu

30

Using Modules

‘require’ functions loads a moduleWhatever 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();

@akshaymathu 31

@akshaymathu

32

A SIMPLE WEB SERVER

Let’s Program

@akshaymathu

33

Hello World

Just one line is needed to write to STDOUTconsole.log(‘Hello World’)

Running the file with Node just worksnode hello_world.js

@akshaymathu

34

Minimalistic HTTP Server

var http = require("http");

on_request = function(request, response) { response.writeHead(200,

{"Content-Type": "text/plain"});

response.write("Hello World");

response.end(); };http.createServer(on_request).listen(8888);Console.log(‘Server Started’);

@akshaymathu

35

Improving the Server

Running this server with Node starts the servernode 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

@akshaymathu

36

Organizing Code

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

@akshaymathu

37

Initial Server Module

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;

@akshaymathu

38

Initial Startup File

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 servernode index.js

But it still returns ‘Hello world’ for all URLs

@akshaymathu

39

Let’s Revise: Parts of URL

https://sub.domain.com:8086/a/folder/file.html?key=val&key=val2#some_place

ProtocolSub-domain, Domain and TLDPortPathFileQuery stringFragment

@akshaymathu

40

Server – Router Interaction

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 moduleSo 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?

@akshaymathu

41

Initial Router

function route(pathname) {console.log("About to route a

request for " + pathname);

}

exports.route = route;

@akshaymathu

42

Router Aware Server

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;

@akshaymathu

43

Making Router Available to Server

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

@akshaymathu

44

Adding Request Handlers

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

@akshaymathu

45

Initial Request Handlers

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;

@akshaymathu

46

Including Handlers

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);

@akshaymathu

47

Change in Server

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;

@akshaymathu

48

Real Routing

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;

@akshaymathu 49

@akshaymathu

50

Done

Did we do everything Correct?

Nop

@akshaymathu

51

What is wrong?

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

@akshaymathu

52

What are the problems?

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

@akshaymathu

53

The Right Way

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

@akshaymathu

54

Corrected Server

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;

@akshaymathu

55

Corrected Router

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;

@akshaymathu

56

Corrected Handlers

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;

@akshaymathu

57

Done

Did we do everything Correct?

Yep

@akshaymathu 58

@akshaymathu

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

60

MVC in Node

Express (Controller)

Mongoose (Model)

Jade (View)

More …

@akshaymathu

61

Thanks

@akshaymathu

top related