25
Building your first Node app with Connect & Express Christian Joudrey - @cjoudrey

Building your first Node app with Connect & Express

Embed Size (px)

DESCRIPTION

Talk given at JS-Montreal #10.

Citation preview

Page 1: Building your first Node app with Connect & Express

Building your first Node app with Connect & Express

Christian Joudrey - @cjoudrey

Page 2: Building your first Node app with Connect & Express

Getting Started

• Node.js: http://nodejs.org/#download

• npm, a package manager for Node:curl http://npmjs.org/install.sh | sh

• Use npm to install Connect and Express for Node:npm install connect && npm install express

• Many more modules at: http://npm.mape.me/

Page 3: Building your first Node app with Connect & Express

Hello World in Node.js

// Load the http modulevar http = require('http');

// Setup a HTTP server, listen on port 8080http.createServer(function (req, res) {  res.writeHead(200, {    'Content-Type': 'text/plain'  });  res.end('Hello World');}).listen(8080, '127.0.0.1');

Page 4: Building your first Node app with Connect & Express

Node's HTTP module

• Very low level.

• No cookie handling or parsing.

• No session support built-in.

• No routing built-in.

• No static file serving.

Page 5: Building your first Node app with Connect & Express

Connect makes it easier

• Static File Server

• Body Decoder

• Cookie Decoder

• Session Provider

• Request Router

• Logs

• Sass/Less Compiler

• Virtual Host Router

Page 6: Building your first Node app with Connect & Express

...but, you decide what blocks you want.

Page 7: Building your first Node app with Connect & Express

Hello World in Connect

// Load the connect modulevar connect = require('connect');

// Setup a HTTP server, listen on port 8080connect.createServer(function (req, res) {  res.writeHead(200, {    'Content-Type': 'text/plain'  });  res.end('Hello World');}).listen(8080, '127.0.0.1');

Page 8: Building your first Node app with Connect & Express

.use() and next()var connect = require('connect');var s = connect.createServer();

s.use(function (req, res, next) {  // Send to next handler if url not /about  if (req.url != '/about') return next();  res.end('About page');});

s.use(function (req, res, next) {  res.end('Default page');});

s.listen(8080, '127.0.0.1');

Page 9: Building your first Node app with Connect & Express

Routing Middlewares.use(connect.router(function(app) {  app.get('/users', function(req, res, next) {    res.end('List users');  });

  app.post('/users', function(req, res, next) {    res.end('Create a new user');  });

  app.get('/user/:id', function(req, res, next) {    if (!is_admin(req)) {      return next(new Error('access denied'));    }    res.end('Edit user ' + req.params.id);  });}));

s.use(function(err, req, res, next) {  res.end(err.message);});

Page 10: Building your first Node app with Connect & Express

Full example with Connectvar connect = require('connect');var s = connect.createServer();

s.use(connect.logger());s.use(connect.favicon(__dirname + '/static/favicon.ico'));s.use(connect.static(__dirname + '/static'));s.use(connect.cookieParser()); // adds req.cookiess.use(connect.bodyParser()); // adds req.body

s.use(connect.router(require('./users'));s.use(connect.router(require('./index'));s.use(function(err, req, res, next) {  res.end('Internal Server Error');});

s.listen(8080, '127.0.0.1');

Page 11: Building your first Node app with Connect & Express

Express is even easier

• Connect is easier than raw node.js, but still low level.

• ...but, it's good for simple RESTful API's

• ...or to make your own framework.

• Express is a simple framework inspired by Sinatra (Ruby).

• It's built on top of Connect.

Page 12: Building your first Node app with Connect & Express

Hello World in Express

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

app.get('/', function(req, res) {  res.send('hello world');});

app.listen(8080);

Page 13: Building your first Node app with Connect & Express

Getting Started with Express

• Generate skeleton apps:express –help

• Generate app with sessions and template engine:express --sessions --template ejs hello

• Generated structure:$ ls hello/app.js  logs  pids  public  test  views

$ ls hello/views/index.ejs  layout.ejs

Page 14: Building your first Node app with Connect & Express

Configurationsapp.configure(function() {  // Global configurations  app.use(express.bodyParser()); // parse incoming data  app.use(express.cookieParser()); // parse cookies  app.use(express.session({ secret: 'your secret' });});

app.configure('development', function() {  // Development configurations  // i.e. Error handler to print errors and show stack?});

app.configure('production', function() {  // Production configurations});

Controlled by:       NODE_ENV=production node app.js

Page 15: Building your first Node app with Connect & Express

Routing

app.get('/users', function(req, res) {  // List user});

app.post('/users', function(req, res) {  // Create user  // req.body contains POST data});

app.get('/user/:id', function(req, res) {  // Edit user  // req.params.id contains value of :id param});

Page 16: Building your first Node app with Connect & Express

Sanitizing Route Params

app.param(':id', function(v) {  return parseInt(v, 10);});

app.get('/user/:id', function(req, res) {  res.send('user id: ' + req.params.id);});

Page 17: Building your first Node app with Connect & Express

Even better...

var integer = function(v) {  return parseInt(v, 10);};

app.param(':id', integer);

app.get('/user/:id', function(req, res) {  res.send('user id: ' + req.params.id);});

Page 18: Building your first Node app with Connect & Express

Route Param Pre-conditions

app.get('/user/:id', function(req, res) {  var id = req.params.id;  User.get(id, function(err, user) {    if (err) return next(err);    res.send('user ' + user.name);  });});

app.put('/user/:id', function(req, res) {  var id = req.params.userId;  User.get(id, function(err, user) {    if (err) return next(err);    user.update(req.body);  });});

Same logic every time there is :id

Page 19: Building your first Node app with Connect & Express

Even better...

var loadUser = function(req, res, next) {  var id = req.params.id;  User.get(id, function(err, user) {    if (err) return next(err);    if (!user) return next(new Error('invalid userId'));    req.user = user;    next();  });});

app.get('/user/:id', loadUser, function(req, res) {  res.send('user ' + req.user.name);});

app.put('/user/:id', loadUser, function(req, res) {  req.user.update(req.body);});

Page 20: Building your first Node app with Connect & Express

You can stack them...

app.put('/user/:id', isAdmin, loadUser, function(req, res) {  req.user.update(req.body);});

app.put('/user/:id', function(req, res, next) {  // Verify if the current user is an admin  isAdmin(req, res, function(err) {    if (err) return next(err);    loadUser(req, res, function(err, user) {      if (err) return next(err);      req.user.update(req.body);    });  });});

...cleaner than...

Page 21: Building your first Node app with Connect & Express

Views

• "Built-in" support for :

o Jade (Haml-like): http://jade-lang.com/

o EJS (Embedded JS): http://embeddedjs.com/

• Support for partials.

Page 22: Building your first Node app with Connect & Express

Rendering Views

app.get('/user/:id', loadUser, function(req, res) {  res.render('user_edit', {    locals: {      user: req.user,      title: 'Edit User ' + req.user.username    }  });});

Page 23: Building your first Node app with Connect & Express

Other useful functions...

• app.helpers(Object)

o Set functions that are available in your views

• app.dynamicHelpers(Object)

o Set helpers that require the req and res objects

• app.error(Function), called when:

o throw new Error()

o next(new Error())

Page 24: Building your first Node app with Connect & Express

Interesting Links

• Lots of Express examples: http://bit.ly/ExpressExamples

• Express Documentation: http://bit.ly/ExpressDocs

• Database wrappers and ORMs:

o Mongoose (MongoDB, ORM-like): https://github.com/LearnBoost/mongoose

o Cradle (CouchDB, HTTP wrapper):https://github.com/cloudhead/cradle

o Couch-ar (CouchDB, Active Record implementation):https://github.com/scottburch/couch-ar

Page 25: Building your first Node app with Connect & Express

Questions? :)