Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Efficient web development with MongoDB and Node.js

Efficient web development with MongoDB and Node.js

Also have a look at the HTML5 version: http://engawa.mongodb-berlin-2013.jit.su/static.html

Avatar for Gerd Jungbluth

Gerd Jungbluth

March 01, 2013
Tweet

More Decks by Gerd Jungbluth

Other Decks in Programming

Transcript

  1. Efficient web development with Efficient web development with MongoDB and

    Node.js MongoDB and Node.js JSON all over JSON all over Berlin, 26.2.2013, Dr. Gerd Jungbluth, Hanka Schmidt Berlin, 26.2.2013, Dr. Gerd Jungbluth, Hanka Schmidt @gjungb @hankasch @gjungb @hankasch
  2. "Efficiency" and the challenges of web "Efficiency" and the challenges

    of web development development Efficiency Efficiency Efficiency Efficiency Efficiency Efficiency Efficiency Efficiency is the extent to which time or effort is well used for the intended task or is the extent to which time or effort is well used for the intended task or purpose. purpose. Efficiency - Wikipedia, the free encyclopedia Efficiency - Wikipedia, the free encyclopedia requirements requirements requirements requirements requirements requirements requirements requirements (rapidly) evolve / (rapidly) evolve / change change change change change change change change • • quality quality quality quality quality quality quality quality and and speed speed speed speed speed speed speed speed matter matter • • continuous integration continuous integration continuous integration continuous integration continuous integration continuous integration continuous integration continuous integration and and test driven test driven test driven test driven test driven test driven test driven test driven development are vital development are vital • • teamwork teamwork teamwork teamwork teamwork teamwork teamwork teamwork is essential is essential • • web apps web apps web apps web apps web apps web apps web apps web apps are driven by are driven by data data data data data data data data • •
  3. MongoDB, Node.js and browsers to the MongoDB, Node.js and browsers

    to the rescue rescue One language to rule them all One language to rule them all Aaron Heckmann - Engineer at 10gen via NodeStack - Online Conference Aaron Heckmann - Engineer at 10gen via NodeStack - Online Conference one one one one one one one one data format ( data format (JSON JSON JSON JSON JSON JSON JSON JSON) ) • • one one one one one one one one programming language ( programming language (JavaScript JavaScript JavaScript JavaScript JavaScript JavaScript JavaScript JavaScript) ) • • one one one one one one one one programming paradigma ( programming paradigma (asynchronous asynchronous asynchronous asynchronous asynchronous asynchronous asynchronous asynchronous | | event driven event driven event driven event driven event driven event driven event driven event driven | | non- non- non- non- non- non- non- non- blocking blocking blocking blocking blocking blocking blocking blocking) ) • •
  4. JSON (JavaScript Object Notation) JSON (JavaScript Object Notation) a a

    syntax syntax syntax syntax syntax syntax syntax syntax for for serializing serializing serializing serializing serializing serializing serializing serializing objects, arrays, numbers, strings, booleans, and null objects, arrays, numbers, strings, booleans, and null JSON - JavaScript | MDN JSON - JavaScript | MDN var o = JSON.parse('{"foo":"bar","baz":true,"tags":["MongoDB","Node.js"]}'); // typeof o === "object" console.log(o.foo); // bar var s = JSON.stringify(o); // typeof s === "string" console.log(s); // {"foo":"bar","baz":true,"tags":["MongoDB","Node.js"]} ​ 2 ​ 6 great for great for persistent persistent persistent persistent persistent persistent persistent persistent storage storage • • great for data great for data transport transport transport transport transport transport transport transport over over networks networks networks networks networks networks networks networks • •
  5. JavaScript JavaScript a a lightweight lightweight lightweight lightweight lightweight lightweight

    lightweight lightweight, interpreted, object-oriented , interpreted, object-oriented programming language programming language programming language programming language programming language programming language programming language programming language with first-class with first-class functions functions JavaScript | MDN JavaScript | MDN established in 1995, established in 1995, standardized standardized standardized standardized standardized standardized standardized standardized in ECMA-262 specification and ISO/IEC in ECMA-262 specification and ISO/IEC 16262 16262 • • executed inside a executed inside a virtual machine virtual machine virtual machine virtual machine virtual machine virtual machine virtual machine virtual machine (in (in mongo mongo Shell, in Node.js, in browsers) Shell, in Node.js, in browsers) • • dynamically typed, flexible, dynamically typed, flexible, fast fast fast fast fast fast fast fast • • supported by a highly active supported by a highly active community community community community community community community community • • great for " great for "rapid application development rapid application development rapid application development rapid application development rapid application development rapid application development rapid application development rapid application development" (RAD) " (RAD) • •
  6. First-class functions First-class functions // a function is an object

    var double = function double(n) { return n * 2; }; typeof double; // "function" double(3); // 6 // functions can be passed as arguments function calculate(v, fn) { return fn(v); } calculate(17, double); // 34 // higher order functions (i.e functions taking functions as arguments or returning a function) // closures (i.e. an inner function has access to variables in the surrounding scope) // anonymous functions (i.e. functions without an identifier) function multiplier(n) { return function(v) { return n * v; }; } var triple = multiplier(3); // typeof triple === "function" triple(9); // 27 calculate(17, triple); // 51 ​ 2 ​ 8 ​ 13 ​ 14 ​ 15
  7. Node.js Node.js a a platform platform platform platform platform platform

    platform platform built on Chrome's JavaScript runtime for easily built on Chrome's JavaScript runtime for easily building building building building building building building building fast, scalable fast, scalable network network applications applications applications applications applications applications applications applications node.js node.js based on based on V8 V8 V8 V8 V8 V8 V8 V8 (Google's JavaScript engine) for JavaScript execution (Google's JavaScript engine) for JavaScript execution • • based on based on libuv libuv libuv libuv libuv libuv libuv libuv (a high performance evented I/O library) for OS interaction (a high performance evented I/O library) for OS interaction • • the the core core core core core core core core (written in C / C++ / JavaScript) is intentionally kept (written in C / C++ / JavaScript) is intentionally kept small small small small small small small small • • user contributed user contributed modules modules modules modules modules modules modules modules available via available via npm npm npm npm npm npm npm npm ("node package manager") ("node package manager") • • executed in a executed in a single thread single thread single thread single thread single thread single thread single thread single thread, demanding , demanding asynchronous asynchronous asynchronous asynchronous asynchronous asynchronous asynchronous asynchronous programming programming • •
  8. Think asynchronously! Think asynchronously! In In event event event event

    event event event event-driven programming, an application expresses -driven programming, an application expresses interest interest interest interest interest interest interest interest in certain events in certain events and responds to them and responds to them when when when when when when when when they occur. they occur. Basics of libuv — An Introduction to libuv Basics of libuv — An Introduction to libuv var p1, p2, query; query = {"sections.pages.headline" : "Think asynchronously!"}; // synchronous, blocking (mongo Shell) p1 = db.presentations.find(query); typeof p1; // "object" // asynchronous, non-blocking (MongoDB native Node.js driver) db.collection("presentations").find(query, function(error, result) { if (error) { throw new Error(error); } p2 = result; }); typeof p2; // undefined ​ 3 ​ 6 ​ 10 ​ 12 ​ 14
  9. Building this data driven, real time Building this data driven,

    real time presentation presentation What? What? What? What? What? What? What? What? the audience the audience You are looking at a You are looking at a single page HTML5 single page HTML5 single page HTML5 single page HTML5 single page HTML5 single page HTML5 single page HTML5 single page HTML5 presentation presentation 1 1. . Client Client Client Client Client Client Client Client side interaction / layout is based on side interaction / layout is based on Flowtime.js Flowtime.js (by (by @marcolago @marcolago) ) 2 2. . We made it We made it data driven data driven data driven data driven data driven data driven data driven data driven powered by MongoDB powered by MongoDB 3 3. . It's a It's a web app web app web app web app web app web app web app web app entirely written in JavaScript entirely written in JavaScript 4 4. .
  10. A walkthrough A walkthrough Setup Node.js Setup Node.js project project

    project project project project project project 1 1. . Build Build data model data model data model data model data model data model data model data model 2 2. . Connect to Connect to MongoDB MongoDB MongoDB MongoDB MongoDB MongoDB MongoDB MongoDB and render HTML dynamically on the and render HTML dynamically on the server server server server server server server server 3 3. . Build a Build a REST API REST API REST API REST API REST API REST API REST API REST API for CRUD for CRUD 4 4. . Access the API Access the API manually manually manually manually manually manually manually manually from the client from the client 5 5. . Use Use AngularJS AngularJS AngularJS AngularJS AngularJS AngularJS AngularJS AngularJS to render HTML dynamically on the to render HTML dynamically on the client client client client client client client client 6 6. .
  11. Our project setup Our project setup package.json package.json { "name":

    "mongodb-berlin-2013", "version": "0.0.1-4", "private": true, "scripts": { "start": "node app" }, "dependencies": { "express": "3.0.6", "ejs": "~0.8", "mongodb": "~1.2", "mongoose": "~3.5", "jsdom": "~0.3.4", "lodash": "~1.0.0" }, "devDependencies": { "yeoman": "~0.9.6", "jasmine-node": "~1.2" }, "subdomain": "engawa.mongodb-berlin-2013", "engines": { "node": "0.8.x" } }
  12. Our data model (using Mongoose ODM) Our data model (using

    Mongoose ODM) schema.js schema.js 'use strict'; /** * @author Gerd Jungbluth */ var Schema = require('mongoose').Schema, AuthorSchema, PresentationSchema, SectionSchema, PageSchema, ParagraphSchema, RealtimeSchema; /** * An author */ exports.AuthorSchema = AuthorSchema = new Schema({ _id : String }); /** * A paragraph */ exports.ParagraphSchema = ParagraphSchema = new Schema({ fragment : { type : Boolean, default : false }, parallax : { active : { type : Boolean, default : false no no no no no no no no normalization / JOINs / SQL normalization / JOINs / SQL • • no no no no no no no no transformation of data transformation of data • • just just plain plain plain plain plain plain plain plain JavaScript JavaScript objects objects objects objects objects objects objects objects • •
  13. Server side assembly (MongoDB / Server side assembly (MongoDB /

    JavaScript) JavaScript) app.js app.js MongoClient.connect(MONGODB_URL, function(error, db) { app.get('/server.html', routes.server(db)); } routes/index.js routes/index.js 'use strict'; /** * @author Gerd Jungbluth */ var ObjectID = require('mongodb').ObjectID; /** * render dynamic presentation on server side * @param {Object} req - request * @param {Object} res - response */ exports.server = function(db) { return function(req, res) { var query; query = { _id : ObjectID.createFromHexString(req.param('presid')) }; db.collection('presentations').findOne(query, function(error, result) { if (error) { throw error;
  14. Server side assembly (HTML / Server side assembly (HTML /

    JavaScript) JavaScript) views/server.ejs views/server.ejs <div class="flowtime"> <% presentation.sections.forEach(function(section, index) { %> <div class="ft-section" data-title="<%= section.title || '' %>"> <% section.pages.forEach(function(page, index) { %> <div class="ft-page" data-title="<%= page.title || '' %>"> <% if (page.headline) { %> <h1><%- page.headline %></h1> <% } %> <% page.paragraphs.forEach(function(paragraph) { %> <%- paragraph.content %> <% }); %> </div> <% }); %> </div> <% }); %> </div>
  15. REST API REST API routes/api/index.js routes/api/index.js app.get(BASE_PATH + 'presentations/:presid/sections/:sectid', readSection(db));

    /** * Reads a single section of a single presentation */ function readSection (db) { return function (req, res) { var query, projection; query = { "_id" : ObjectID.createFromHexString(req.params.presid) }; projection = { "sections" : { "$elemMatch" : { "_id" : ObjectID.createFromHexString(req.params.sectid) } } }; db.collection('presentations').findOne(query, projection, function (error, result) { var section; if (error) { throw new Error(error); } section = result.sections[0]; res.send(section || {}); }); }; } Take a look at Take a look at the API the API
  16. A REST client in the browser A REST client in

    the browser /scripts/restclient.js /scripts/restclient.js var RESTclient = (function ($) { var BASE_PATH = '/api/1', client; function buildUrl (options) { var ret = BASE_PATH; if (options.presid) { ret = ret + '/presentations/' + options.presid; } if (options.sectid) { ret = ret + '/sections/' + options.sectid; } if (options.pageid) { ret = ret + '/pages/' + options.pageid; } return ret; } function updatePage (options, headline, callback) { var url = buildUrl(options); $.ajax({ url : url, method : 'PUT', data : { headline : headline } }); } client = { updatePage : updatePage }; return client; }(jQuery)); RESTclient.updatePage({ presid:'512a2212968914d029000004', sectid:'512a2212968914d02900001f', RESTclient.updatePage({ presid:'512a2212968914d029000004', sectid:'512a2212968914d02900001f', pageid:'512a2212968914d029000039' }, 'A REST client in the browser'); pageid:'512a2212968914d029000039' }, 'A REST client in the browser');
  17. Client side assembly (AngularJS) Client side assembly (AngularJS) scripts/controllers/main.js scripts/controllers/main.js

    client.html client.html $http.get('/api/1/presentations/' + presid) .success(function(data, status, headers, config) { $scope.presentation = data; $window.document.title = $scope.presentation.meta.title; $timeout(initFlowtime, 0); }) .error(function (data, status, headers, config) { console.error(arguments); }); <div class="flowtime" ng-controller="MainCtrl"> <div ng-repeat="section in presentation.sections" class="ft-section" data-title="{{section.title}}"> <div ng-repeat="page in section.pages" class="ft-page" data-title="{{page.title}}"> <h1 ng-show="page.headline != null" ng-bind-html-unsafe="page.headline"></h1> <div ng-repeat="paragraph in page.paragraphs" ng-bind-html-unsafe="paragraph.content"></div> </div> </div> </div>
  18. Conclusion Conclusion MongoDB, Node.js and JavaScript make web development efficient

    and fun! MongoDB, Node.js and JavaScript make web development efficient and fun! The Node.JS MongoDB Driver Manual The Node.JS MongoDB Driver Manual • • Mongoose ODM Mongoose ODM • • JavaScript | MDN JavaScript | MDN • • Node.js Manual & Documentation Node.js Manual & Documentation • • AngularJS: Developer Guide AngularJS: Developer Guide • • An Introduction to libuv An Introduction to libuv • • Chrome V8 — Google Developers Chrome V8 — Google Developers • •
  19. Finally Finally Thank Thank you you you you you you

    you you! ! the presenters the presenters Ask questions! Ask questions! 1 1. . Get in touch! Get in touch! @hankaSch @hankaSch, , @gjungb @gjungb, , @UseMoncodo @UseMoncodo 2 2. . Be a Be a Moncodo Moncodo beta tester, our beta tester, our #MongoDB #MongoDB "model / code / deploy" web "model / code / deploy" web app app 3 3. . Take a Coffee Break! Take a Coffee Break! 4 4. .