JS-IL: Getting MEAN in 1 Hour

693 views

Published on

Building a full stack MEAN stack app in 1 hour at JS-IL 2014

Published in: Technology
0 Comments
2 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
693
On SlideShare
0
From Embeds
0
Number of Embeds
76
Actions
Shares
0
Downloads
18
Comments
0
Likes
2
Embeds 0
No embeds

No notes for slide

JS-IL: Getting MEAN in 1 Hour

  1. 1. 1 Hour MEAN Stack Hackathon Valeri Karpov Software Engineer, MongoDB www.thecodebarbarian.com www.slideshare.net/vkarpov15 github.com/vkarpov15 @code_barbarian Building a Full Stack Single Page App and Workflow
  2. 2. * Who is this guy? •Coined the MEAN stack in April ‘13 •Maintains mongoose, omni-di •Contributor to node-mongodb-native, mquery, etc. •AngularJS since 0.9.4 in 2010 •Production MEAN apps: Ascot Project, Bookalokal •Former CTO, LevelUp
  3. 3. * General Outline •Building a single page app - LeanMEAN •Food journal counts calories for you (FitDay) •MEAN = MongoDB, ExpressJS, AngularJS, NodeJS •Additional tools: • browserify • make • omni-di • mongoose • MongoDB 2.6 text search • PassportJS / Twitter oauth
  4. 4. * What we’re building
  5. 5. * Beyond the Hack •Nitty-gritty deep dive into code and workflow •Build tools and workflow: browserify, make •Code organization: browserify, omni-di •Unit testing and benchmarks: mocha
  6. 6. * Step by Step •Step 0: Understand SR-25 data set •Step 1: Create Express app •Step 2: Restructure Express app •Step 3: Construct Models •Step 4: Define API •Step 5: Set up client-side routing •Step 6: Client-side integration with API
  7. 7. * Step by Step, Continued •Step 7: Unit testing •Step 8: Authentication
  8. 8. * Follow along on GitHub
  9. 9. * Step 0: USDA SR-25 Nutrition Data •Need data: calories, carbs, lipids for common foods •Thankfully available from USDA’s website •mongorestore-friendly dump for MongoDB here •My blog post about the data set
  10. 10. * What does SR-25 data look like?
  11. 11. * What Nutrients Look Like
  12. 12. * What Weights Look Like
  13. 13. * Simple SR-25 Query •How many carbs in 1 serving of raw kale? •Good baby step for food journal
  14. 14. * Text Search in MongoDB 2.6 •Don’t want users to have to enter “Kale, raw” •Example: top 3 results for “grass-fed beef”
  15. 15. * Text Search in MongoDB 2.6 •Static data = perfect use case for text search •Need to create a text index first from shell: • db.nutrition.ensureIndex({ description : “text” }); •Read more here •Note: mongoose >= 3.8.9 required
  16. 16. * Step 1: Creating an Express App •Can create an Express app with 2 commands: • `npm install express -g` installs Express • `express lean-mean-nutrition-sample` creates the app
  17. 17. * Step 2: Restructuring the App •Single page app doesn’t need Jade templating •views folder obsolete •Set up package.json file •package.json - workflow for setting up env: • `git clone`: pull down repo • `npm install`: install dependencies • `npm test`: run tests • `npm start`: start the server
  18. 18. * passport.json Setup
  19. 19. * Step 3: Create Database Schema “Ontology deals with questions concerning what entities exist or can be said to exist, and how such entities can be grouped, related within a hierarchy, and subdivided according to similarities and differences” - Wikipedia article on ontology
  20. 20. * Quick Overview of Mongoose •ODM for MongoDB and NodeJS •Schema design and validation •Convenience objects •MEAN Stack’s official best friend
  21. 21. * Objects in LeanMEAN World •FoodItem: from SR-25 •User: because any real API scopes by user •Day: the FoodItems a User ate on a given date
  22. 22. * First, SR-25 Nutrition Item Schema
  23. 23. * Having Users is a Positive
  24. 24. * Constructing the Day Schema
  25. 25. * Day Schema Subtleties •Want to let user select from multiple weights •Want user to enter custom amount for a weight •Difference between selectedWeight / weights •Nutrient amounts per 100G
  26. 26. * Omni-di to tie this all together •Avoid dependency hell: don’t require in every file!
  27. 27. * Omni-di’s `assemble()` function
  28. 28. * Step 4: Define an API Complexity creeps up on you like a snake in the grass. Good thing we have a Mongoose on our side!
  29. 29. * The API Methods
  30. 30. * Search for a Food Item Note: text search API is atypical, docs here
  31. 31. * Load a Day
  32. 32. * Save a Day
  33. 33. * Wait, Where’s The Work? •Mongoose validates client foods data w/ schema •Only modifying foods - free access control •No need to check if date exists: upsert flag •isNew flag in `GET /api/date/:date`
  34. 34. * Step 5: AngularJS + Browserify •Single Page App: how to manage code bloat?
  35. 35. * Browserify = Write Node For Client •AngularJS dependency in package.json •Never deal with flakey CDNs again!
  36. 36. * Build Process with Browserify •Output: all.js, contains all JS in 1 file •Input: all files in client directory + dependencies •browserify -o ./public/javascripts/all.js client/* •Or, make build_client
  37. 37. * Single Page App Basics
  38. 38. * What index.html Looks Like ng-view is where the magic happens
  39. 39. * http://localhost:3000/#/
  40. 40. * http://localhost:3000/#/track
  41. 41. * Why Single Page App? •No server side templating: • Better server throughput • Cleaner separation of concerns • Less bandwidth usage •More control over UX
  42. 42. * Step 6: Let’s Build a Client! •AngularJS controller for each particular view •Right now only need TrackController •Controller talks to server •Controller provides API for UI
  43. 43. * Modifying the AngularJS Module
  44. 44. * TrackController Structure
  45. 45. * TrackController API
  46. 46. * TrackController in the HTML
  47. 47. * Implementation of loadDay()
  48. 48. * Implementation of recalculate() ?
  49. 49. * Code Sharing - calculations.js
  50. 50. * NodeJS SPA and Code Sharing •Code sharing is trivial with browserify •MEAN stack principle: The objects your server deals with should be almost identical to the objects your client deals with and the objects stored in your database. •Same objects => easy code sharing •Calculations a good candidate in this case
  51. 51. * search() call
  52. 52. * addFood() call
  53. 53. * Step 7: Unit Testing with Kittens
  54. 54. * Get Serious About Testing •Foundation: proper unit tests, automation •Heuristic: code “works” iff npm test succeeds •Grunt or Makefile, either works well
  55. 55. * Omni-di and unit tests •Beauty of DI: easy to control how much to stub •For unit tests, stub everything
  56. 56. * Testing PUT /api/day/:date
  57. 57. * Testing PUT /api/day/:date
  58. 58. * Testing TrackController
  59. 59. * Testing TrackController
  60. 60. * Tying Tests Together with make
  61. 61. * Browserify SPA Testing Advantages •Code sharing •Single test framework - Mocha
  62. 62. * Step 8: Authentication •Last step!
  63. 63. * Authentication in SPA •PassportJS makes oauth easy •But… requires redirect •Not that much of a problem •Handle cases where user hits API but not logged in
  64. 64. * Setting up app.js with Passport
  65. 65. * checkLogin middleware
  66. 66. * checkLogin and TrackController
  67. 67. * Passport Setup
  68. 68. * Client-side User Tracking
  69. 69. * Displaying the Logged In User
  70. 70. * And that’s a wrap! Time to Review •Single page app with MEAN stack •AngularJS routing •Browserify for building client code •Twitter Oauth •Elegant MongoDB features
  71. 71. * And that’s a wrap! Time to Review •Mongoose = work-free API (with right schema!) •MongoDB 2.6 text search
  72. 72. * Thanks for Listening! •Slides on: • Twitter: @code_barbarian • Slideshare: slideshare.net/vkarpov15 •Repo on github: github.com/vkarpov15/lean-mean- nutrition-sample •Blog post on SR-25 data set

×