Your browser doesn't support the features required by impress.js, so you are presented with a simplified version of this presentation.

For the best experience please use the latest Chrome, Safari or Firefox browser.


Prof. Cesare Pautasso
[email protected]



var msg = "x:"; //private
var f = function(x) { 
  return msg + " " + x; 
module.exports.f = f; //public

Export module functions making them part of module.exports

var module = require('module'); //library module
var my_module = require('./my_module'); //local module

Import modules with require



  "name": "my-app",
  "description": "My Web Application",
  "version": "0.0.1",
  "dependencies": {
    "express": "4.x"

dependencies lists the required modules and their version


The Node Package Manager helps you to:

npm init

interactively create a new package.json

npm install

download and install the dependencies

npm install package --save

download and install the package and add it to the dependencies listed in package.json

Model View Controller

  • User input is handled by the Controller which may change the state of the Model
  • The Views display the current state of the Model (and may receive notifications about state changes by observing it)

MVC on the Web 1.0

MVC on the Web 2.0

Express MVC

Express MVC

var express = require('express');
var app = express(); 
  function(req, res) { 
db.findAll(function(error, model) { res.render('view', model); })
}); app.listen(8888);


var router = express.Router();
router.METHOD('URI Template', callback)

METHOD = {get, put, post, delete, all}

app.use('URI', router);

Activate the router under the 'URI' path

  function(req, res){
    res.send('user ' +; 
  function(req, res){
    res.send('file path: ' + req.params);

Parse the Request Body

var bodyParser = require('body-parser');
  extended: true
app.put('/blog/:year/:id?', //? optional 
  function(req, res){
    var year = req.params.year; 
    var id = || 0; //default 0 
var body = req.body;

Content-Type Negotiation

Content-Type: application/json
if ("application/json")) { 
  //request body is JSON 
Accept: text/html
//request asks for HTML content in the response
if (req.accepts("html")) { 
  //set Response Content-Type Header
Content-Type: text/html


How to run the same code for all requests?

Use a middleware function, which can intercept, modify and validate all requests

app.use(function(req, res, next) {
//intercept the request
  console.log(req.method+" "+req.url);
//do not forget to call next

middleware can be attached to a specific router

router.use(function(req, res, next){...});

Reusable middleware: body-parser cookie-parser method-override serve-static Morgan (Logging).


function(model) { return html }

Views are template files that present content to the user: variables, arrays and objects that are used in views are passed by the controller to be rendered by the view.

Views should not contain complex business logic; only the elementary control structures necessary to perform particular operations, such as the iteration over collections, and simple filters.

Views (Manual)

function(model) { 
  var html = []; 
  if (model.user) {
    html.push('<h2>' + + '</h2>');
  return html.join();

Views (Rendered)

res.render('view template', { model } );

Invoke a template to render the view

res.render('index.dust', { model } );
res.render('index.ejs', { model } );

Explicitly choose the template engine to use

app.set('view engine', 'dust');
res.render('index', { model } );

Configure express to choose the default template engine

Template Engines

Embedded JavaScript allowed

  1. EJS
  2. underscore.js
  3. Jade
  4. jQuery templates

Logic-less templates

Logic-less code more likely to work both on client and server-side

  1. dust.js
  2. mustache
  3. handlebars
  4. Google Closure Templates

Embedded JS Templates


var model = { 
  user: { name: 'CP' }
res.render('index.ejs', model );


<% if (user) { %> 
  <h2>< %></h2>
<% } %>



Embedded JS Templates


<h1><%= title %></h1> 
<% for(var i=0; i<list.length; i++) {%>
  <li><%= link_to(list[i], 
                  ‘users/'+list[i]) %></li>
<% } %>

Dust.JS Templates


var model = { 
  user: { name: 'CP' }
res.render('index.dust', model );





Dust.JS Example


var model = { title: "Hello World", 
               list: ["a", "b"] };
res.render("list.dust", model);


  <li><a href="users/{.}">{.}</a></li>

{#}{/} for each

{.} current array element


Working with Databases


  • Relational Databases
  • Tables (Relations) store well-structured data according to a predefined Schema
  • Queries defined according to the standard Structured Query Language
  • Strong transactional guarantees (ACID)


  • Non-relational Databases (Object-oriented databases, document databases, graph databases, key-value stores, XML databases)
  • Schema-less (semi-structured heterogeneous data stores)
  • Highly scalable with relaxed transactional guarantees and limited query expressivity



  • mySQL
  • PostgreSQL
  • Oracle
  • Microsoft SQL Server
  • IBM DB2


  • CouchDB
  • MongoDB
  • Apache JackRabbit
  • Neo4j
  • MemCacheDB
  • BigTable
  • Redis
  • Apache Hadoop


A collection is a set of JSON objects, which may or may not have the same structure

1. Connecting

var mongoose = require('mongoose');
// The MongoDB Server should be running
// for the connection to work

2. Schema Definition

var CommentsSchema = new mongoose.Schema ({ 
   person     : String
 , comment    : { type: String, required: true }
 , created_at : { type: Date, default: } 

By default fields are optional (required: false)

2. Schema Definition

var PostSchema = new mongoose.Schema({ 
    _id : mongoose.Types.ObjectId
  , author: String
  , title : String
  , body : String
  , created_at : Date
  , comments : [CommentsSchema]
//Create the Collection ‘Post’ using Schema
mongoose.model('Post', PostSchema); 
var Post = mongoose.model('Post');

3. Queries

  function (err, posts) { 
  	//for each post in posts
  function (err, post) { 
  	if (!err) {  //found post with id

3. Queries

Post.find({}, {title: 1}
  function (err, posts) { 
    //for each post in posts
    //the post will only include
    //_id, title
Post.find({}, {title: 0}
  function (err, posts) { 
    //for each post in posts
    //the post will only include
    //_id, author, body, created_at, comments

Control which fields to include (1) or exclude (0)

4. Create and Save

Save also works with updates

var post = new Post(
     { title: params['title'],
        body: params['body'], 
  created_at: new Date() }); (err) { //save failed

5. Delete

  function (err, post) { 
    if (!err) {
      post.remove(function (err, removed) {
        if (err) throw err;
        //post successfully removed

Schema Middleware

var schema = new Schema(..);
schema.pre('save', function (next) {
  // here 'this' refers to the object being saved
  // do something before saving 'this'
  // call the next middleware
});'save', function (doc) {
  // 'doc' refers to the object that has been saved
  // do something after saving 'doc'

Events can be 'init', 'validate', 'save', 'remove'



Use a spacebar or arrow keys to navigate