Building your first Node app with Connect & Express
Upcoming SlideShare
Loading in...5
×
 

Building your first Node app with Connect & Express

on

  • 27,231 views

Talk given at JS-Montreal #10.

Talk given at JS-Montreal #10.

Statistics

Views

Total Views
27,231
Slideshare-icon Views on SlideShare
27,230
Embed Views
1

Actions

Likes
19
Downloads
210
Comments
0

1 Embed 1

http://a0.twimg.com 1

Accessibility

Categories

Upload Details

Uploaded via as Microsoft PowerPoint

Usage Rights

CC Attribution License

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment
  • - brief overview of what node has built in - overview of how to use Connect is - overview of how to use ExpressJS is - ask questions at any time
  • - Explain the basics of http module and createServer function. - req is object that has request stuff (url, get params, body, cookies, ..) - res is object that has response stuff (set headers, send data, ..)
  • - just a very simple http wrapper - gotta code everything up on your own
  • - connect makes it easier - comes with many useful bundles - typical functionalities that you will need
  • - similar to node's http module - if put all in same callback, can get messy
  • - use() is a different way of setting callbacks - we call them Middleware - behind use() is a stack, first in, first out - can use next() to trigger next handler - can have infinite handles
  • - a better way of setting routes - HTTP verbs - capture url params using colon - can also use regular expressions - next() Error handling - don't need to use next to pass to next() handler. - can organize by module
  • - stack the middlewares you want - called in order - seperate controllers into modules
  • - easier than node, but still low level - No view engine, gotta add your own - Configurations, on your own - good for restful since dont need view engine - express is like sinatra - built with connect - all the features of connect, but more
  • - try it out with CLI tool, its easy - multiple template engines (jade, ejs, mustache, etc...) - css compiler support (less, sass)
  • - configuration blocks - can be controlled with NODE_ENV environment variable
  • - Uses Connect.router - Can use HTTP verbs - Can capture params - req.body for POST - req.params for url params
  • - can sanitize parameters - force type on params - some cases in couchdb that you can nosql injections. this would prevent
  • - generalize formatters - reuseable
  • - we want to validate user exists in both situations - we aren't reusing the code - same logic every time
  • - you could also validate that the userId is an integer using same method. - and call next() if not int
  • - you can add as many as you need - this example, checking login and checking user exists
  • - built in ejs and jade - ejs is html with embedded JS - jade is like haml - partials, can render views inside a view
  • - automatically loads views/user_edit.jade - .render automatically includes layout.jade
  • - cant go through all of them, just so you know - app.helpers takes an object and exposes in views - app.dynamicHelpers when you want to use request vars - app error, 
  • Interesting Links

Building your first Node app with Connect & Express Building your first Node app with Connect & Express Presentation Transcript

  • Building your first Node app with Connect & Express Christian Joudrey - @cjoudrey
  • 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/
  • Hello World in Node.js
    • // Load the http module
    • var http = require(' http ');
    • // Setup a HTTP server, listen on port 8080
    • http.createServer(function (req, res) {
    •    res.writeHead(200, {
    •      ' Content-Type ': ' text/plain '
    •    });
    •    res.end(' Hello World ');
    • }).listen(8080, ' 127.0.0.1 ');
  • 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.
  • Connect makes it easier
      • Static File Server
      • Body Decoder
      • Cookie Decoder
      • Session Provider
      • Request Router
      • Logs
      • Sass/Less Compiler
      • Virtual Host Router
  • ...but, you decide what blocks you want.
  • Hello World in Connect
    • // Load the connect module
    • var  connect = require(' connect ');
    • // Setup a HTTP server, listen on port 8080
    • connect.createServer(function (req, res) {
    •    res.writeHead(200, {
    •      ' Content-Type ': ' text/plain '
    •    });
    •    res.end(' Hello World ');
    • }).listen(8080, ' 127.0.0.1 ');
  • .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 ');
  • Routing Middleware
    • s.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);
    • });
  • Full example with Connect
    • var 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.cookies
    • s.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 ');
  • 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.
  • Hello World in Express
    • var  express = require(' express ');
    • var  app = express.createServer();
    • app.get(' / ', function(req, res) {
    •    res.send(' hello world ');
    • });
    • app.listen(8080);
  • 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
  • Configurations
    • app.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
  • 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
    • });
  • 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);
    • });
  • 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);
    • });
  • 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
  • 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);
    • });
  • 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...
  • Views
      • "Built-in" support for :
        • Jade (Haml-like):  http://jade-lang.com/
        • EJS (Embedded JS):  http://embeddedjs.com/
      • Support for partials.
  • Rendering Views
    • app.get(' /user/:id ', loadUser, function(req, res) {
    •    res.render(' user_edit ', {
    •      locals: {
    •        user: req.user,
    •        title: ' Edit User ' + req.user.username
    •      }
    •    });
    • });
  • Other useful functions...
      • app.helpers(Object)
        • Set functions that are available in your views
      • app.dynamicHelpers(Object)
        • Set helpers that require the req and res objects
      • app.error(Function), called when:
        • throw new Error()
        • next(new Error())
  • Interesting Links
      • Lots of Express examples:  http://bit.ly/ExpressExamples
      • Express Documentation:   http://bit.ly/ExpressDocs
      • Database wrappers and ORMs:
        • Mongoose (MongoDB, ORM-like):  https://github.com/LearnBoost/mongoose
        • Cradle (CouchDB, HTTP wrapper): https://github.com/cloudhead/cradle
        • Couch-ar (CouchDB, Active Record implementation): https://github.com/scottburch/couch-ar
  • Questions? :)