MEAN Stack Workshop at Node Philly, 4/9/14

1,890 views

Published on

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

No Downloads
Views
Total views
1,890
On SlideShare
0
From Embeds
0
Number of Embeds
91
Actions
Shares
0
Downloads
52
Comments
0
Likes
6
Embeds 0
No embeds

No notes for slide

MEAN Stack Workshop at Node Philly, 4/9/14

  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 Food Journal Single Page App + Workflow
  2. 2. * Who is this guy? •Coined the MEAN stack in April ‘13 •Contributor to: • node-mongodb-native • mongoose • mquery • omni-di, etc. •AngularJS since 0.9.4 in 2010 •Production MEAN apps: Ascot Project, Bookalokal
  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
  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. * Why Two Food Item Services? Text score sorting in Mongoose, see pull request Will be fixed in next version of Mongoose!
  29. 29. * 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!
  30. 30. * The API Methods
  31. 31. * Search for a Food Item Note: text search API is atypical, docs here
  32. 32. * Load a Day
  33. 33. * Save a Day
  34. 34. * 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`
  35. 35. * Step 5: AngularJS + Browserify •Single Page App: how to manage code bloat?
  36. 36. * Browserify = Write Node For Client •AngularJS dependency in package.json •Never deal with flakey CDNs again!
  37. 37. * 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
  38. 38. * Single Page App Basics
  39. 39. * What index.html Looks Like ng-view is where the magic happens
  40. 40. * http://localhost:3000/#/
  41. 41. * http://localhost:3000/#/track
  42. 42. * Why Single Page App? •No server side templating: • Better server throughput • Cleaner separation of concerns • Less bandwidth usage •More control over UX
  43. 43. * 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
  44. 44. * Modifying the AngularJS Module
  45. 45. * TrackController Structure
  46. 46. * TrackController API
  47. 47. * TrackController in the HTML
  48. 48. * Implementation of loadDay()
  49. 49. * Implementation of recalculate() ?
  50. 50. * Code Sharing - calculations.js
  51. 51. * 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
  52. 52. * search() call
  53. 53. * addFood() call
  54. 54. * Step 7: Unit Testing with Kittens
  55. 55. * Get Serious About Testing •Foundation: proper unit tests, automation •Heuristic: code “works” iff npm test succeeds •Grunt or Makefile, either works well
  56. 56. * Omni-di and unit tests •Beauty of DI: easy to control how much to stub •For unit tests, stub everything
  57. 57. * Testing PUT /api/day/:date
  58. 58. * Testing PUT /api/day/:date
  59. 59. * Testing TrackController
  60. 60. * Testing TrackController
  61. 61. * Tying Tests Together with make
  62. 62. * Browserify SPA Testing Advantages •Code sharing •Single test framework - Mocha
  63. 63. * Step 8: Authentication •Last step!
  64. 64. * 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
  65. 65. * Setting up app.js with Passport
  66. 66. * checkLogin middleware
  67. 67. * checkLogin and TrackController
  68. 68. * Passport Setup
  69. 69. * Client-side User Tracking
  70. 70. * Displaying the Logged In User
  71. 71. * Displaying the Logged In User
  72. 72. * And that’s a wrap! Time to Review •Single page app with MEAN stack •AngularJS routing •Browserify for building client code •Validating complex objects with Mongoose •MongoDB text search •Testing and automation •Twitter Oauth
  73. 73. * 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

×