Developing web-apps like it's 2013
Upcoming SlideShare
Loading in...5
×
 

Developing web-apps like it's 2013

on

  • 4,395 vues

A case-study of using node.js to develop entreprise applications. Includes real-world examples for express.js, mongoose.js and async.js

A case-study of using node.js to develop entreprise applications. Includes real-world examples for express.js, mongoose.js and async.js

Statistiques

Vues

Total des vues
4,395
Vues sur SlideShare
4,282
Vues externes
113

Actions

J'aime
15
Téléchargements
76
Commentaires
5

5 Ajouts 113

http://faz.my 76
http://192.168.1.137 13
https://twitter.com 12
http://localhost 9
http://www.onlydoo.com 3

Accessibilité

Catégories

Détails de l'import

Uploaded via as Microsoft PowerPoint

Droits d'utilisation

© Tous droits réservés

Report content

Signalé comme inapproprié Signaler comme inapproprié
Signaler comme inapproprié

Indiquez la raison pour laquelle vous avez signalé cette présentation comme n'étant pas appropriée.

Annuler

15 of 5 Publier un commentaire

  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Votre message apparaîtra ici
    Processing...
  • i found this really cool and very informative
    Are you sure you want to
    Votre message apparaîtra ici
    Processing...
  • i found this very informative thanks a lot for sharing
    Are you sure you want to
    Votre message apparaîtra ici
    Processing...
  • i found this very informative thanks a lot for sharing
    Are you sure you want to
    Votre message apparaîtra ici
    Processing...
  • what's fun in read?
    Are you sure you want to
    Votre message apparaîtra ici
    Processing...
  • Cool!!!
    Are you sure you want to
    Votre message apparaîtra ici
    Processing...
Poster un commentaire
Modifier votre commentaire

    Developing web-apps like it's 2013 Developing web-apps like it's 2013 Presentation Transcript

    • Developing web-apps like it’s2013 a case-study of using node.js to build entreprise applications 1
    • Who?Laurent Van Basselaere@Laurent_VBI do stuff with codeat Arhs Developments 2
    • ARHS Developments10 years, 300 peopleConsulting & fixed price projectsSoftware (Java)Business Intelligence 3
    • testing 4
    • Testing 5
    • 6
    • MS Access? SRSLY?MS AccessMultiple copiesSingle userNo remote useLame 7
    • Fatman FTWMS Access BrowserMultiple versions CentralizedSingle user Unlimited usersNo remote use EverywhereLame Awesome 8
    • We wrote a web-app 9
    • Fatman tech stackBootstrap asyncKnockout underscoreExpress momentNodeMongooseMongoDB 10
    • Elegant MongoDB object modeling forNode.jsORM seemed desirableClean object model to use in app code 11
    • Schemavar mongoose = require(‘mongoose’);mongoose.connect(‘localhost’, ‘fatman’);var ProjectSchema = new mongoose.Schema({ id : String , name : String , users : [String]});var Project = mongoose.model(Project, ProjectSchema); 12
    • CREATE/EDITvar project = new Project({ id: ‘AKCT’ , name: ‘GOCA Newsoft AKCT’ , users: [‘vanbasla’, ‘grosjech’]});project.save(function (err){ //… callback after save}); 13
    • RETRIEVE// find project by idProject.where(‘id’, ‘AKCT’) .findOne(function(err, project) { // do something with search result });// find my projectsProject.find({‘users’: username}) .exec(function(err, projects){ // do something with search results }); 14
    • MORE Schemafunction trim(value){ return value ? value.trim() : value;}function lessThan80chars(value){ return value.length <= 80;}var ProjectSchema = new mongoose.Schema({ id : {type: String, required: true, unique: true} , name : {type: String, set: trim, validate: [ lessThan80chars, Value too long. Max 80 characters.]}}); 15
    • Advanced// staticsProjectSchema.statics.findById = function(projectId, cb){ Project.where(id, projectId).findOne(cb);};// methodsProjectSchema.methods.issueTrackerEnabled = function() { return this.issueTracker != null;};// middlewareProjectCaseSchema.pre(‘remove’, function(next) { // do something when a Project is deleted next();}); 16
    • In fatmanWe use setters + pre-save middlewareto keep history of edits. 17
    • In fatman// creates a setter for fieldfunction setter(field) { return function setField(newValue) { this._oldValues = this._oldValues || {}; this._oldValues[field] = this[field]; return newValue; }}var TestCaseSchema = new Schema({ id: {type:Number,index:true}, description: {type:String, set: setter(description)}, history: [Schema.Types.Mixed]}); 18
    • In fatman// Populate history before save.TestCaseSchema.pre(save, function (next) { var self = this , oldValues = this._oldValues || {}; delete this._oldValues; this.modifiedPaths.forEach(function (field) { if (field in oldValues) { self.history.push({ ‘old: oldValues[field], ‘new’: self[field] }); } }); next();}); 19
    • Express is a minimal and flexiblenode.js web application framework.Simple and modularNode de-facto standard
    • Hello Expressvar express = require(express), consolidate = require(consolidate);// create an express appvar app = express();// configure view engineapp.engine(html, consolidate.handlebars);app.set(views, __dirname + /views);// configure a route with an url parameterapp.get(/hello/:name, hello);function hello(req, res, next){ res.render(hello.html, { name : req.params.name });}app.listen(1337);console.log(Listening on port 1337);
    • controllerfunction list (req, res, next){ Project.findById(req.params.projectId, function(err, project){ if (err) return next(err); TestCase.find({‘project’: project}, function(err, testcases){ if (err) return next(err); res.render(‘testcases.html’, { ‘project’: project, ‘testcases’: testcases }); }); });}
    • controllerfunction show (req, res, next){ Project.findById(req.params.projectId, function(err, project){ if (err) return next(err); TestCase.findOne({‘project’:project, ‘id’:id}, function(err, tc){ if (err) return next(err); res.render(‘testcase.html’, { ‘project’: project, ‘testcase’: tc }); }); });}
    • controllerfunction save (req, res, next){ Project.findById(req.params.projectId, function(err, project){ if (err) return next(err); var tc = new TestCase(req.body); tc.project = project; tc.save(function(err, tc){ if (err) return next(err); // redirect after post res.redirect(req.url); }); });}
    • MIDDLEWAREfunction loadProject(req, res, next){ Project.findById(req.params.projectId, function(err, project){ if (err) return next(err); res.locals.project = project; next(); });}// before all routes requiring a projectapp.all(/:projectId/*, loadProject);
    • BETTERfunction list (req, res, next){ var project = res.locals.project; TestCase.find({‘project’:project}, function(err, testcases){ if (err) return next(err); res.render(‘testcases.html’, { ‘testcases’: testcases }); });}
    • BETTerfunction show (req, res, next){ var project = res.locals.project; TestCase.findOne({‘project’:project, ‘id’:id}, function(err, tc){ if (err) return next(err); res.render(‘testcase.html’, { ‘testcase’: tc }); });}
    • BETTerfunction save (req, res, next){ var tc = new TestCase(req.body); tc.project = res.locals.project; tc.save(function(err){ if (err) return next(err); res.redirect(req.url); });}
    • pyramid of doomfunction search (req, res, next){ Project.findById(projectId, function(err, project){ if (err) return next(err); TestPlan.findByIdentifier(project, testPlanId, function(err, testPlan) { if (err) return next(err); var tags = getTagsFromRequest(req); TestCase.findByTag(testPlan, tags, function(err, tagQuery, testCases){ if (err) return next(err); TestCase.countTags(tagQuery, function(err, tagsResult) { if (err) return next(err); res.render(‘search’, { ‘testCases’ : testCases, ‘tagsResult’ : tagsResult, ‘project’ : project, ‘testPlan’ : testPlan, ‘tags’ : tags }); }); }); }); });}
    • Async.jsAsync is a utility module which providesstraight-forward, powerful functions forworking with asynchronous JavaScript
    • pyramid NO MOREAsync.jsfunction search (req, res, next){ async.waterfall([ function(cb){ Project.findById(projectId, cb); }, function(cb, project){ res.locals.project = project; TestPlan.findByIdentifier(project, testPlanId, cb); }, function(cb, testPlan){ res.locals.testPlan = testPlan; var tags = res.locals.tags = getTagsFromRequest(req); TestCase.findByTag(testPlan, tags, cb); }, function(cb, tagQuery, testCases){ res.locals.testCases = testCases; TestCase.countTags(tagQuery, cb); } ], function(err, tagsResult){ if (err) return next(err); res.render(‘search’, tagsResult); });}
    • MORE async Async.jsvar ids = [‘AKCT’, ‘FATMAN’];var projects = [];ids.forEach(function(id){ Project.findById(id, function(err, project){ projects.push(project); });});res.render(‘projects’, {‘project’ : projects}); WRONG
    • MORE async Async.jsvar ids = [‘AKCT’, ‘FATMAN’];var projects = [];async.each(ids, function(id, next){ Project.findById(id, function(err, project){ projects.push(project); next(); })}, function(err){ res.render(‘projects’, {‘projects’: projects});});
    • MORE async Async.jsCollections Control floweach seriesmap parallelfilter whilstreject doWhilstreduce untildetect doUntilsortBy waterfall… …
    • FATMAN60 days dev6 months prod12 projects (2 to 10 users)
    • FATMAN
    • FATMAN
    • FATMAN