node architecture and getting started with express
TRANSCRIPT
![Page 1: Node Architecture and Getting Started with Express](https://reader030.vdocument.in/reader030/viewer/2022032620/55c5a694bb61eb1b2a8b4764/html5/thumbnails/1.jpg)
NODE.JS ARCHITECTURE ANDGETTING STARTED WITH EXPRESS.JS
Jordan Kasper | Developer Evangelist
![Page 2: Node Architecture and Getting Started with Express](https://reader030.vdocument.in/reader030/viewer/2022032620/55c5a694bb61eb1b2a8b4764/html5/thumbnails/2.jpg)
NODE.JS ARCHITECTURE
![Page 3: Node Architecture and Getting Started with Express](https://reader030.vdocument.in/reader030/viewer/2022032620/55c5a694bb61eb1b2a8b4764/html5/thumbnails/3.jpg)
MODULARITY
![Page 4: Node Architecture and Getting Started with Express](https://reader030.vdocument.in/reader030/viewer/2022032620/55c5a694bb61eb1b2a8b4764/html5/thumbnails/4.jpg)
MODULE PATTERNSThere are various patterns...
Simple Object APIRevealing Module (Function Initialization)Object Constructor
![Page 5: Node Architecture and Getting Started with Express](https://reader030.vdocument.in/reader030/viewer/2022032620/55c5a694bb61eb1b2a8b4764/html5/thumbnails/5.jpg)
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](https://reader030.vdocument.in/reader030/viewer/2022032620/55c5a694bb61eb1b2a8b4764/html5/thumbnails/6.jpg)
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](https://reader030.vdocument.in/reader030/viewer/2022032620/55c5a694bb61eb1b2a8b4764/html5/thumbnails/7.jpg)
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](https://reader030.vdocument.in/reader030/viewer/2022032620/55c5a694bb61eb1b2a8b4764/html5/thumbnails/8.jpg)
SCALING
![Page 9: Node Architecture and Getting Started with Express](https://reader030.vdocument.in/reader030/viewer/2022032620/55c5a694bb61eb1b2a8b4764/html5/thumbnails/9.jpg)
![Page 10: Node Architecture and Getting Started with Express](https://reader030.vdocument.in/reader030/viewer/2022032620/55c5a694bb61eb1b2a8b4764/html5/thumbnails/10.jpg)
VERTICAL SCALING
![Page 11: Node Architecture and Getting Started with Express](https://reader030.vdocument.in/reader030/viewer/2022032620/55c5a694bb61eb1b2a8b4764/html5/thumbnails/11.jpg)
NODE CLUSTERING
![Page 12: Node Architecture and Getting Started with Express](https://reader030.vdocument.in/reader030/viewer/2022032620/55c5a694bb61eb1b2a8b4764/html5/thumbnails/12.jpg)
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](https://reader030.vdocument.in/reader030/viewer/2022032620/55c5a694bb61eb1b2a8b4764/html5/thumbnails/13.jpg)
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](https://reader030.vdocument.in/reader030/viewer/2022032620/55c5a694bb61eb1b2a8b4764/html5/thumbnails/14.jpg)
LOAD BALANCINGcluster uses a simple round-robin approach...
...but there are better ways!
![Page 15: Node Architecture and Getting Started with Express](https://reader030.vdocument.in/reader030/viewer/2022032620/55c5a694bb61eb1b2a8b4764/html5/thumbnails/15.jpg)
HORIZONTAL SCALING
![Page 16: Node Architecture and Getting Started with Express](https://reader030.vdocument.in/reader030/viewer/2022032620/55c5a694bb61eb1b2a8b4764/html5/thumbnails/16.jpg)
![Page 17: Node Architecture and Getting Started with Express](https://reader030.vdocument.in/reader030/viewer/2022032620/55c5a694bb61eb1b2a8b4764/html5/thumbnails/17.jpg)
HORIZONTAL SCALING
![Page 18: Node Architecture and Getting Started with Express](https://reader030.vdocument.in/reader030/viewer/2022032620/55c5a694bb61eb1b2a8b4764/html5/thumbnails/18.jpg)
![Page 20: Node Architecture and Getting Started with Express](https://reader030.vdocument.in/reader030/viewer/2022032620/55c5a694bb61eb1b2a8b4764/html5/thumbnails/20.jpg)
BASIC NGINX CONFIGserver listen 80 location / proxy_pass http://localhost:3000;
location /static/ root /var/www/myapp/public;
$ sudo service nginx start
![Page 21: Node Architecture and Getting Started with Express](https://reader030.vdocument.in/reader030/viewer/2022032620/55c5a694bb61eb1b2a8b4764/html5/thumbnails/21.jpg)
NGINX LOAD BALANCERhttp upstream myapp least_conn; # roundrobin is the default... # Or use ip_hash; for "sticky" sessions... server www1.myapp.com; server www2.myapp.com; server www3.myapp.com;
server listen 80 location / proxy_pass http://myapp;
![Page 22: Node Architecture and Getting Started with Express](https://reader030.vdocument.in/reader030/viewer/2022032620/55c5a694bb61eb1b2a8b4764/html5/thumbnails/22.jpg)
STRONGLOOP AND NGINXIf you're using strong-pm you can use the
!StrongLoop nginx
controller~$ npm install g strongnginxcontroller
~$ slnginxctlinstall
Install the Controller on the load balancing host...
![Page 23: Node Architecture and Getting Started with Express](https://reader030.vdocument.in/reader030/viewer/2022032620/55c5a694bb61eb1b2a8b4764/html5/thumbnails/23.jpg)
...then manage the load balancing infrastructure from:StrongLoop Arc
![Page 24: Node Architecture and Getting Started with Express](https://reader030.vdocument.in/reader030/viewer/2022032620/55c5a694bb61eb1b2a8b4764/html5/thumbnails/24.jpg)
![Page 25: Node Architecture and Getting Started with Express](https://reader030.vdocument.in/reader030/viewer/2022032620/55c5a694bb61eb1b2a8b4764/html5/thumbnails/25.jpg)
SCALING WITH STRONGLOOP ARC
![Page 26: Node Architecture and Getting Started with Express](https://reader030.vdocument.in/reader030/viewer/2022032620/55c5a694bb61eb1b2a8b4764/html5/thumbnails/26.jpg)
![Page 28: Node Architecture and Getting Started with Express](https://reader030.vdocument.in/reader030/viewer/2022032620/55c5a694bb61eb1b2a8b4764/html5/thumbnails/28.jpg)
EXPRESS.JS
![Page 29: Node Architecture and Getting Started with Express](https://reader030.vdocument.in/reader030/viewer/2022032620/55c5a694bb61eb1b2a8b4764/html5/thumbnails/29.jpg)
EXPRESS.JSFast, light, unopinionated framework for web applications.
![Page 30: Node Architecture and Getting Started with Express](https://reader030.vdocument.in/reader030/viewer/2022032620/55c5a694bb61eb1b2a8b4764/html5/thumbnails/30.jpg)
EXPRESS HELLO WORLD~/myapp$ npm init...
~/myapp$ npm install express save
![Page 31: Node Architecture and Getting Started with Express](https://reader030.vdocument.in/reader030/viewer/2022032620/55c5a694bb61eb1b2a8b4764/html5/thumbnails/31.jpg)
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);
~/myapp$ node app.js
![Page 32: Node Architecture and Getting Started with Express](https://reader030.vdocument.in/reader030/viewer/2022032620/55c5a694bb61eb1b2a8b4764/html5/thumbnails/32.jpg)
SCAFFOLDING AN EXPRESS APP
![Page 33: Node Architecture and Getting Started with Express](https://reader030.vdocument.in/reader030/viewer/2022032620/55c5a694bb61eb1b2a8b4764/html5/thumbnails/33.jpg)
SCAFFOLDING EXPRESSInstall the CLI generator first...
~$ npm install g expressgenerator
~$ express myapp...~$ cd myapp~/myapp$ npm install
![Page 34: Node Architecture and Getting Started with Express](https://reader030.vdocument.in/reader030/viewer/2022032620/55c5a694bb61eb1b2a8b4764/html5/thumbnails/34.jpg)
A SCAFFOLDED APPmyapp/ |_ bin # execution file (shell script) |_ node_modules |_ public # images, css, fonts, etc |_ routes # Node.js routing code |_ views # serverside templates |_ app.js |_ package.json
![Page 35: Node Architecture and Getting Started with Express](https://reader030.vdocument.in/reader030/viewer/2022032620/55c5a694bb61eb1b2a8b4764/html5/thumbnails/35.jpg)
RUNNING A SCAFFOLDED APP~/myapp$ npm start
..., "scripts": "start": "node ./bin/www" , ...
![Page 36: Node Architecture and Getting Started with Express](https://reader030.vdocument.in/reader030/viewer/2022032620/55c5a694bb61eb1b2a8b4764/html5/thumbnails/36.jpg)
CONFIGURING EXPRESS
![Page 37: Node Architecture and Getting Started with Express](https://reader030.vdocument.in/reader030/viewer/2022032620/55c5a694bb61eb1b2a8b4764/html5/thumbnails/37.jpg)
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](https://reader030.vdocument.in/reader030/viewer/2022032620/55c5a694bb61eb1b2a8b4764/html5/thumbnails/38.jpg)
REQUEST ROUTING
![Page 39: Node Architecture and Getting Started with Express](https://reader030.vdocument.in/reader030/viewer/2022032620/55c5a694bb61eb1b2a8b4764/html5/thumbnails/39.jpg)
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](https://reader030.vdocument.in/reader030/viewer/2022032620/55c5a694bb61eb1b2a8b4764/html5/thumbnails/40.jpg)
POST ROUTINGmyApp.post('/user', function createUser(req, res, next) // Create the user record...
res.redirect('/myaccount'););
![Page 41: Node Architecture and Getting Started with Express](https://reader030.vdocument.in/reader030/viewer/2022032620/55c5a694bb61eb1b2a8b4764/html5/thumbnails/41.jpg)
POST ROUTINGmyApp.post('/user', function createUser(req, res, next) // Create the user record...
// Where do we get the data from?
res.redirect('/myaccount'););
![Page 42: Node Architecture and Getting Started with Express](https://reader030.vdocument.in/reader030/viewer/2022032620/55c5a694bb61eb1b2a8b4764/html5/thumbnails/42.jpg)
MIDDLEWARE
![Page 43: Node Architecture and Getting Started with Express](https://reader030.vdocument.in/reader030/viewer/2022032620/55c5a694bb61eb1b2a8b4764/html5/thumbnails/43.jpg)
![Page 44: Node Architecture and Getting Started with Express](https://reader030.vdocument.in/reader030/viewer/2022032620/55c5a694bb61eb1b2a8b4764/html5/thumbnails/44.jpg)
MIDDLEWARE EXAMPLESvar express = require('express'), bodyParser = require('bodyparser');
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](https://reader030.vdocument.in/reader030/viewer/2022032620/55c5a694bb61eb1b2a8b4764/html5/thumbnails/45.jpg)
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](https://reader030.vdocument.in/reader030/viewer/2022032620/55c5a694bb61eb1b2a8b4764/html5/thumbnails/46.jpg)
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](https://reader030.vdocument.in/reader030/viewer/2022032620/55c5a694bb61eb1b2a8b4764/html5/thumbnails/47.jpg)
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](https://reader030.vdocument.in/reader030/viewer/2022032620/55c5a694bb61eb1b2a8b4764/html5/thumbnails/48.jpg)
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](https://reader030.vdocument.in/reader030/viewer/2022032620/55c5a694bb61eb1b2a8b4764/html5/thumbnails/49.jpg)
HANDLING MIDDLEWARE ERRORSapp.use(function(err, req, res, next) // Do whatever you need to...
if (err.code === 404)
res.redirect('/error404');
else // Or you can keep processing this (or a new) Error next(err); );
![Page 50: Node Architecture and Getting Started with Express](https://reader030.vdocument.in/reader030/viewer/2022032620/55c5a694bb61eb1b2a8b4764/html5/thumbnails/50.jpg)
![Page 51: Node Architecture and Getting Started with Express](https://reader030.vdocument.in/reader030/viewer/2022032620/55c5a694bb61eb1b2a8b4764/html5/thumbnails/51.jpg)
HANDLING MIDDLEWARE ERRORSAlways set up a "catchall" error handler!
![Page 52: Node Architecture and Getting Started with Express](https://reader030.vdocument.in/reader030/viewer/2022032620/55c5a694bb61eb1b2a8b4764/html5/thumbnails/52.jpg)
SERVER-SIDE TEMPLATING
![Page 53: Node Architecture and Getting Started with Express](https://reader030.vdocument.in/reader030/viewer/2022032620/55c5a694bb61eb1b2a8b4764/html5/thumbnails/53.jpg)
TEMPLATESSmall blocks that we can plug data into at run-time
// /views/index.jadedoctype htmlhtml head title #title body section.mainbody.clear #homepageText
![Page 54: Node Architecture and Getting Started with Express](https://reader030.vdocument.in/reader030/viewer/2022032620/55c5a694bb61eb1b2a8b4764/html5/thumbnails/54.jpg)
TEMPLATING ENGINE~/myapp$ 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](https://reader030.vdocument.in/reader030/viewer/2022032620/55c5a694bb61eb1b2a8b4764/html5/thumbnails/55.jpg)
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](https://reader030.vdocument.in/reader030/viewer/2022032620/55c5a694bb61eb1b2a8b4764/html5/thumbnails/56.jpg)
DON'T FORGET YOUR MODULARITY!
![Page 57: Node Architecture and Getting Started with Express](https://reader030.vdocument.in/reader030/viewer/2022032620/55c5a694bb61eb1b2a8b4764/html5/thumbnails/57.jpg)
NOT MODULAR...var express = require('express'), bodyParser = require('bodyparser');
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/myaccount', ... ); ););
![Page 58: Node Architecture and Getting Started with Express](https://reader030.vdocument.in/reader030/viewer/2022032620/55c5a694bb61eb1b2a8b4764/html5/thumbnails/58.jpg)
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/myaccount', user: user ););
router.post('/', function(req, res, next) // Create a user... res.redirect('user/myaccount', user: user ););
module.exports = router;
![Page 59: Node Architecture and Getting Started with Express](https://reader030.vdocument.in/reader030/viewer/2022032620/55c5a694bb61eb1b2a8b4764/html5/thumbnails/59.jpg)
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](https://reader030.vdocument.in/reader030/viewer/2022032620/55c5a694bb61eb1b2a8b4764/html5/thumbnails/60.jpg)
REQUEST OBJECT
![Page 61: Node Architecture and Getting Started with Express](https://reader030.vdocument.in/reader030/viewer/2022032620/55c5a694bb61eb1b2a8b4764/html5/thumbnails/61.jpg)
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](https://reader030.vdocument.in/reader030/viewer/2022032620/55c5a694bb61eb1b2a8b4764/html5/thumbnails/62.jpg)
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](https://reader030.vdocument.in/reader030/viewer/2022032620/55c5a694bb61eb1b2a8b4764/html5/thumbnails/63.jpg)
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](https://reader030.vdocument.in/reader030/viewer/2022032620/55c5a694bb61eb1b2a8b4764/html5/thumbnails/64.jpg)
RESPONSE OBJECT
![Page 65: Node Architecture and Getting Started with Express](https://reader030.vdocument.in/reader030/viewer/2022032620/55c5a694bb61eb1b2a8b4764/html5/thumbnails/65.jpg)
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](https://reader030.vdocument.in/reader030/viewer/2022032620/55c5a694bb61eb1b2a8b4764/html5/thumbnails/66.jpg)
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](https://reader030.vdocument.in/reader030/viewer/2022032620/55c5a694bb61eb1b2a8b4764/html5/thumbnails/67.jpg)
QUESTIONS?NODE.JS ARCHITECTURE AND
GETTING STARTED WITH EXPRESS.JS
Jordan Kasper | Developer EvangelistJoin us for more events!
strongloop.com/developers/events