0
Developing web-apps like it’s2013  a case-study of using node.js to build         entreprise applications                 ...
Who?Laurent Van Basselaere@Laurent_VBI do stuff with codeat Arhs Developments                         2
ARHS Developments10 years, 300 peopleConsulting & fixed price projectsSoftware (Java)Business Intelligence                ...
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   ...
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                       ...
Schemavar mongoose = require(‘mongoose’);mongoose.connect(‘localhost’, ‘fatman’);var ProjectSchema = new mongoose.Schema({...
CREATE/EDITvar project = new Project({    id: ‘AKCT’  , name: ‘GOCA Newsoft AKCT’  , users: [‘vanbasla’, ‘grosjech’]});pro...
RETRIEVE// find project by idProject.where(‘id’, ‘AKCT’)       .findOne(function(err, project) {           // do something...
MORE Schemafunction trim(value){      return value ? value.trim() : value;}function lessThan80chars(value){      return va...
Advanced// staticsProjectSchema.statics.findById = function(projectId, cb){  Project.where(id, projectId).findOne(cb);};//...
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 = ...
In fatman// Populate history before save.TestCaseSchema.pre(save, function (next) {  var self = this    , oldValues = this...
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 = expre...
controllerfunction list (req, res, next){  Project.findById(req.params.projectId, function(err, project){    if (err) retu...
controllerfunction show (req, res, next){  Project.findById(req.params.projectId, function(err, project){    if (err) retu...
controllerfunction save (req, res, next){  Project.findById(req.params.projectId, function(err, project){    if (err) retu...
MIDDLEWAREfunction loadProject(req, res, next){  Project.findById(req.params.projectId, function(err, project){    if (err...
BETTERfunction list (req, res, next){  var project = res.locals.project;  TestCase.find({‘project’:project}, function(err,...
BETTerfunction show (req, res, next){  var project = res.locals.project;  TestCase.findOne({‘project’:project, ‘id’:id}, f...
BETTerfunction save (req, res, next){  var tc = new TestCase(req.body);  tc.project = res.locals.project;  tc.save(functio...
pyramid of doomfunction search (req, res, next){  Project.findById(projectId, function(err, project){    if (err) return n...
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(project...
MORE async                              Async.jsvar ids = [‘AKCT’, ‘FATMAN’];var projects = [];ids.forEach(function(id){  ...
MORE async                              Async.jsvar ids = [‘AKCT’, ‘FATMAN’];var projects = [];async.each(ids, function(id...
MORE async                Async.jsCollections   Control floweach          seriesmap           parallelfilter        whilst...
FATMAN60 days dev6 months prod12 projects (2 to 10 users)
FATMAN
FATMAN
FATMAN
Prochain SlideShare
Chargement dans... 5
×

Developing web-apps like it's 2013

3,951

Published on

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

Published in: Technologies
5 commentaires
15 mentions J'aime
Statistiques
Remarques
Aucun téléchargement
Vues
Total des vues
3,951
Sur Slideshare
0
À partir des ajouts
0
Nombre d'ajouts
2
Actions
Partages
0
Téléchargements
77
Commentaires
5
J'aime
15
Ajouts 0
No embeds

No notes for slide

Transcript of "Developing web-apps like it's 2013"

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

    Clipping is a handy way to collect important slides you want to go back to later.

×