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

Like this? Share it with your network

Share

Developing web-apps like it's 2013

le

  • 4,531 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,531
Vues sur SlideShare
4,416
Vues externes
115

Actions

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

5 Ajouts 115

http://faz.my 78
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
  • Full Name Full Name Comment goes here.
    Êtes-vous sûr de vouloir
    Votre message apparaîtra ici
    Processing...
  • i found this really cool and very informative
    Êtes-vous sûr de vouloir
    Votre message apparaîtra ici
    Processing...
  • i found this very informative thanks a lot for sharing
    Êtes-vous sûr de vouloir
    Votre message apparaîtra ici
    Processing...
  • i found this very informative thanks a lot for sharing
    Êtes-vous sûr de vouloir
    Votre message apparaîtra ici
    Processing...
  • what's fun in read?
    Êtes-vous sûr de vouloir
    Votre message apparaîtra ici
    Processing...
  • Cool!!!
    Êtes-vous sûr de vouloir
    Votre message apparaîtra ici
    Processing...
Poster un commentaire
Modifier votre commentaire

Developing web-apps like it's 2013 Presentation Transcript

  • 1. Developing web-apps like it’s2013 a case-study of using node.js to build entreprise applications 1
  • 2. Who?Laurent Van Basselaere@Laurent_VBI do stuff with codeat Arhs Developments 2
  • 3. ARHS Developments10 years, 300 peopleConsulting & fixed price projectsSoftware (Java)Business Intelligence 3
  • 4. testing 4
  • 5. Testing 5
  • 6. 6
  • 7. MS Access? SRSLY?MS AccessMultiple copiesSingle userNo remote useLame 7
  • 8. Fatman FTWMS Access BrowserMultiple versions CentralizedSingle user Unlimited usersNo remote use EverywhereLame Awesome 8
  • 9. We wrote a web-app 9
  • 10. Fatman tech stackBootstrap asyncKnockout underscoreExpress momentNodeMongooseMongoDB 10
  • 11. Elegant MongoDB object modeling forNode.jsORM seemed desirableClean object model to use in app code 11
  • 12. 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
  • 13. CREATE/EDITvar project = new Project({ id: ‘AKCT’ , name: ‘GOCA Newsoft AKCT’ , users: [‘vanbasla’, ‘grosjech’]});project.save(function (err){ //… callback after save}); 13
  • 14. 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
  • 15. 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
  • 16. 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
  • 17. In fatmanWe use setters + pre-save middlewareto keep history of edits. 17
  • 18. 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
  • 19. 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
  • 20. Express is a minimal and flexiblenode.js web application framework.Simple and modularNode de-facto standard
  • 21. 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);
  • 22. 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 }); }); });}
  • 23. 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 }); }); });}
  • 24. 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); }); });}
  • 25. 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);
  • 26. 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 }); });}
  • 27. 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 }); });}
  • 28. 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); });}
  • 29. 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 }); }); }); }); });}
  • 30. Async.jsAsync is a utility module which providesstraight-forward, powerful functions forworking with asynchronous JavaScript
  • 31. 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); });}
  • 32. 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
  • 33. 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});});
  • 34. MORE async Async.jsCollections Control floweach seriesmap parallelfilter whilstreject doWhilstreduce untildetect doUntilsortBy waterfall… …
  • 35. FATMAN60 days dev6 months prod12 projects (2 to 10 users)
  • 36. FATMAN
  • 37. FATMAN
  • 38. FATMAN