67
NODE.JS ARCHITECTURE AND GETTING STARTED WITH EXPRESS.JS Jordan Kasper | Developer Evangelist

Node Architecture and Getting Started with Express

Embed Size (px)

Citation preview

Page 1: Node Architecture and Getting Started with Express

NODE.JS ARCHITECTURE ANDGETTING STARTED WITH EXPRESS.JS

Jordan Kasper | Developer Evangelist

Page 2: Node Architecture and Getting Started with Express

NODE.JS ARCHITECTURE

Page 3: Node Architecture and Getting Started with Express

MODULARITY

Page 4: Node Architecture and Getting Started with Express

MODULE PATTERNSThere are various patterns...

Simple Object APIRevealing Module (Function Initialization)Object Constructor

Page 5: Node Architecture and Getting Started with Express

SIMPLE OBJECT API// lib/employee.jsmodule.exports = salary: 50000, giveRaise: function( amount ) salary += amount; ;

Why not always use simple objects?Modules are cached!

Page 6: Node Architecture and Getting Started with Express

REVEALING MODULE PATTERNmodule.exports = function createWorker( options )

// Setup...

return salary: 50000, giveRaise: function( amount ) this.salary += amount; ;;

Page 7: Node Architecture and Getting Started with Express

OBJECT CONSTRUCTOR PATTERNvar Worker = module.exports = function Worker( options ) // ...;

Worker.prototype.salary = 50000;Worker.prototype.giveRaise = function( amount ) this.salary += amount;;

Page 8: Node Architecture and Getting Started with Express

SCALING

Page 9: Node Architecture and Getting Started with Express
Page 10: Node Architecture and Getting Started with Express

VERTICAL SCALING

Page 11: Node Architecture and Getting Started with Express

NODE CLUSTERING

Page 12: Node Architecture and Getting Started with Express

var http = require('http'), cluster = require('cluster');

if (cluster.isMaster)

for (var i = 0; i < numCPUCores; i++) cluster.fork(); ;

else

http .createServer(function(req, res) // ... ) .listen(8080, ...););

Page 13: Node Architecture and Getting Started with Express

USING A PROCESS MANAGEREasy clustering and scaling without altering application

codeStrongLoop Process Manager (strong-pm)PM2

Comparison Chart

Forever

Page 14: Node Architecture and Getting Started with Express

LOAD BALANCINGcluster uses a simple round-robin approach...

...but there are better ways!

Page 15: Node Architecture and Getting Started with Express

HORIZONTAL SCALING

Page 16: Node Architecture and Getting Started with Express
Page 17: Node Architecture and Getting Started with Express

HORIZONTAL SCALING

Page 18: Node Architecture and Getting Started with Express
Page 20: Node Architecture and Getting Started with Express

BASIC NGINX CONFIGserver listen 80 location / proxy_pass http://localhost:3000;

location /static/ root /var/www/my­app/public;

$ sudo service nginx start

Page 21: Node Architecture and Getting Started with Express

NGINX LOAD BALANCERhttp upstream myapp least_conn; # round­robin is the default... # Or use ip_hash; for "sticky" sessions... server www1.my­app.com; server www2.my­app.com; server www3.my­app.com;

server listen 80 location / proxy_pass http://myapp;

Page 22: Node Architecture and Getting Started with Express

STRONGLOOP AND NGINXIf you're using strong-pm you can use the

!StrongLoop nginx

controller~$ npm install ­g strong­nginx­controller

~$ sl­nginx­ctl­install

Install the Controller on the load balancing host...

Page 23: Node Architecture and Getting Started with Express

...then manage the load balancing infrastructure from:StrongLoop Arc

Page 24: Node Architecture and Getting Started with Express
Page 25: Node Architecture and Getting Started with Express

SCALING WITH STRONGLOOP ARC

Page 26: Node Architecture and Getting Started with Express
Page 28: Node Architecture and Getting Started with Express

EXPRESS.JS

Page 29: Node Architecture and Getting Started with Express

EXPRESS.JSFast, light, unopinionated framework for web applications.

Page 30: Node Architecture and Getting Started with Express

EXPRESS HELLO WORLD~/my­app$ npm init...

~/my­app$ npm install express ­­save

Page 31: Node Architecture and Getting Started with Express

EXPRESS HELLO WORLD// in app.jsvar express = require('express');var myApp = express();

myApp.get('/', function handleRoot(req, res, next) res.send('Hello World!'););

myApp.listen(8080);

~/my­app$ node app.js

Page 32: Node Architecture and Getting Started with Express

SCAFFOLDING AN EXPRESS APP

Page 33: Node Architecture and Getting Started with Express

SCAFFOLDING EXPRESSInstall the CLI generator first...

~$ npm install ­g express­generator

~$ express my­app...~$ cd my­app~/my­app$ npm install

Page 34: Node Architecture and Getting Started with Express

A SCAFFOLDED APPmy­app/ |_ bin # execution file (shell script) |_ node_modules |_ public # images, css, fonts, etc |_ routes # Node.js routing code |_ views # server­side templates |_ app.js |_ package.json

Page 35: Node Architecture and Getting Started with Express

RUNNING A SCAFFOLDED APP~/my­app$ npm start

..., "scripts": "start": "node ./bin/www" , ...

Page 36: Node Architecture and Getting Started with Express

CONFIGURING EXPRESS

Page 37: Node Architecture and Getting Started with Express

CONFIGURING EXPRESSvar app = express();

app.set('views', 'views');app.set('view engine', 'jade');

app.set('port', process.env.PORT || 3000);app.set('foo', 'bar');

server.listen( app.get('port') );

Page 38: Node Architecture and Getting Started with Express

REQUEST ROUTING

Page 39: Node Architecture and Getting Started with Express

BASIC ROUTINGvar express = require('express');var myApp = express();

myApp.get('/', function handleRoot(req, res, next) res.send('Hello World!'););

myApp.listen( 3000 );

Page 40: Node Architecture and Getting Started with Express

POST ROUTINGmyApp.post('/user', function createUser(req, res, next) // Create the user record...

res.redirect('/my­account'););

Page 41: Node Architecture and Getting Started with Express

POST ROUTINGmyApp.post('/user', function createUser(req, res, next) // Create the user record...

// Where do we get the data from?

res.redirect('/my­account'););

Page 42: Node Architecture and Getting Started with Express

MIDDLEWARE

Page 43: Node Architecture and Getting Started with Express
Page 44: Node Architecture and Getting Started with Express

MIDDLEWARE EXAMPLESvar express = require('express'), bodyParser = require('body­parser');

var app = express();

// app config...

// Parse POST form data...app.use( bodyParser.urlencoded( extended: false ) );

app.post('/user', function createUser() var user = username: req.body.username, ... ; ...);

Page 45: Node Architecture and Getting Started with Express

ORDER MATTERS!Middleware are executed in the order specified

app.use( express.logger('dev') );

app.use( myAuthModule() );

app.use( bodyParser.json() );

app.use(bodyParser.urlencoded( extended: false ));

app.use(express.static(path.join(__dirname, 'public')));

// Routing middleware...

Page 46: Node Architecture and Getting Started with Express

MIDDLEWARE - WHEN DOES IT END?Middleware processing ends when next() is not called

(or an error is generated)app.use(bodyParser.json());app.use(bodyParser.urlencoded( extended: false ));

app.get('/about', function aboutUs(req, res, next)

res.send('We are StrongLoop!');

// no call to next());

app.get('/user', ...);

Page 47: Node Architecture and Getting Started with Express

CUSTOM MIDDLEWAREapp.use(function (req, res, next) // Do some work...

// Modify the req or res...

// execute the callback when done next(););

Page 48: Node Architecture and Getting Started with Express

CUSTOM MIDDLEWARE - ERRORSapp.use(function (req, res, next) // do something...

if (thereWasAnError) var err = new Error(' ... '); next( err ); return;

// No error, so we proceed...

next(););

Page 49: Node Architecture and Getting Started with Express

HANDLING MIDDLEWARE ERRORSapp.use(function(err, req, res, next) // Do whatever you need to...

if (err.code === 404)

res.redirect('/error­404');

else // Or you can keep processing this (or a new) Error next(err); );

Page 50: Node Architecture and Getting Started with Express
Page 51: Node Architecture and Getting Started with Express

HANDLING MIDDLEWARE ERRORSAlways set up a "catchall" error handler!

Page 52: Node Architecture and Getting Started with Express

SERVER-SIDE TEMPLATING

Page 53: Node Architecture and Getting Started with Express

TEMPLATESSmall blocks that we can plug data into at run-time

//­ /views/index.jadedoctype htmlhtml head title #title body section.main­body.clear #homepageText

Page 54: Node Architecture and Getting Started with Express

TEMPLATING ENGINE~/my­app$ npm install ­­save jade

var app = express();

app.set('views', 'views');app.set('view engine', 'jade');

Page 55: Node Architecture and Getting Started with Express

USING A TEMPLATEapp.get('/' function handleRoot(req, res, next)

res.render('index', title: 'StrongLoop ­ Home', homepageText: 'We all love StrongLoop!' );

);

Page 56: Node Architecture and Getting Started with Express

DON'T FORGET YOUR MODULARITY!

Page 57: Node Architecture and Getting Started with Express

NOT MODULAR...var express = require('express'), bodyParser = require('body­parser');

var app = express();

// app config and other middleware...

app.post('/user', function createUser() var user = username: req.body.username, ... ;

db.create(user, function() res.render('user/my­account', ... ); ););

Page 58: Node Architecture and Getting Started with Express

THE 4.0 ROUTER INTERFACE// in routes/users.jsvar express = require('express');var router = express.Router();

router.get('/', function(req, res, next) // Get a list of users... res.render('user/list', results: users ););

router.get('/:id', function(req, res, next) // Get a single user... res.render('user/my­account', user: user ););

router.post('/', function(req, res, next) // Create a user... res.redirect('user/my­account', user: user ););

module.exports = router;

Page 59: Node Architecture and Getting Started with Express

THE 4.0 ROUTER INTERFACE// in app.jsvar express = require('express'), ...;

var app = express();

// app config and middleware...

app.use('/users', require('./routes/users'));

Page 60: Node Architecture and Getting Started with Express

REQUEST OBJECT

Page 61: Node Architecture and Getting Started with Express

QUERY PARAMETERSapp.get('/users', function (req, res, next)

var limit = req.query.limit || 10, users = [];

// Retrieve all users...

res.render('user/list', results: users, nextIndex: 11 ););

Page 62: Node Architecture and Getting Started with Express

URL PARAMETERSapp.get('/users/:id', function (req, res, next)

var id = req.params.id, user = null;

// Retrieve a single user...

if (req.xhr) res.json( user: user ); else res.render('user/single', user: user ); );

Page 63: Node Architecture and Getting Started with Express

URL PARAMETERSapp.get(/\/users\/(\d+)$/, function (req, res, next)

var id = req.params[0], user = null;

// Retrieve a single user... // ...);

Page 64: Node Architecture and Getting Started with Express

RESPONSE OBJECT

Page 65: Node Architecture and Getting Started with Express

RESPONSE METHODSresponse.send(data) or response.end(data)

response.status(httpStatus)

response.send(201, someData)

response.sendfile('path/to/someFile.json')

response.download('/report-12345.pdf')

Page 66: Node Architecture and Getting Started with Express

HTTP STATUS CODES2XX: for successfully processed requests3XX: for redirections or cache information4XX: for client-side errors5XX: for server-side errors

Page 67: Node Architecture and Getting Started with Express

QUESTIONS?NODE.JS ARCHITECTURE AND

GETTING STARTED WITH EXPRESS.JS

Jordan Kasper | Developer EvangelistJoin us for more events!

strongloop.com/developers/events