mean stack workshop at node philly, 4/9/14
TRANSCRIPT
![Page 1: MEAN Stack Workshop at Node Philly, 4/9/14](https://reader034.vdocuments.us/reader034/viewer/2022042714/5553aa14b4c905d9448b47d5/html5/thumbnails/1.jpg)
1 Hour MEAN Stack Hackathon
Valeri KarpovSoftware Engineer, MongoDBwww.thecodebarbarian.com
www.slideshare.net/vkarpov15github.com/vkarpov15
@code_barbarian
Building a Food Journal Single Page App + Workflow
![Page 2: MEAN Stack Workshop at Node Philly, 4/9/14](https://reader034.vdocuments.us/reader034/viewer/2022042714/5553aa14b4c905d9448b47d5/html5/thumbnails/2.jpg)
*
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
![Page 3: MEAN Stack Workshop at Node Philly, 4/9/14](https://reader034.vdocuments.us/reader034/viewer/2022042714/5553aa14b4c905d9448b47d5/html5/thumbnails/3.jpg)
*
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
![Page 4: MEAN Stack Workshop at Node Philly, 4/9/14](https://reader034.vdocuments.us/reader034/viewer/2022042714/5553aa14b4c905d9448b47d5/html5/thumbnails/4.jpg)
*
What we’re building
![Page 5: MEAN Stack Workshop at Node Philly, 4/9/14](https://reader034.vdocuments.us/reader034/viewer/2022042714/5553aa14b4c905d9448b47d5/html5/thumbnails/5.jpg)
*
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
![Page 6: MEAN Stack Workshop at Node Philly, 4/9/14](https://reader034.vdocuments.us/reader034/viewer/2022042714/5553aa14b4c905d9448b47d5/html5/thumbnails/6.jpg)
*
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
![Page 7: MEAN Stack Workshop at Node Philly, 4/9/14](https://reader034.vdocuments.us/reader034/viewer/2022042714/5553aa14b4c905d9448b47d5/html5/thumbnails/7.jpg)
*
Step by Step, Continued
•Step 7: Unit testing
•Step 8: Authentication
![Page 9: MEAN Stack Workshop at Node Philly, 4/9/14](https://reader034.vdocuments.us/reader034/viewer/2022042714/5553aa14b4c905d9448b47d5/html5/thumbnails/9.jpg)
*
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
![Page 10: MEAN Stack Workshop at Node Philly, 4/9/14](https://reader034.vdocuments.us/reader034/viewer/2022042714/5553aa14b4c905d9448b47d5/html5/thumbnails/10.jpg)
*
What does SR-25 data look like?
![Page 11: MEAN Stack Workshop at Node Philly, 4/9/14](https://reader034.vdocuments.us/reader034/viewer/2022042714/5553aa14b4c905d9448b47d5/html5/thumbnails/11.jpg)
*
What Nutrients Look Like
![Page 12: MEAN Stack Workshop at Node Philly, 4/9/14](https://reader034.vdocuments.us/reader034/viewer/2022042714/5553aa14b4c905d9448b47d5/html5/thumbnails/12.jpg)
*
What Weights Look Like
![Page 13: MEAN Stack Workshop at Node Philly, 4/9/14](https://reader034.vdocuments.us/reader034/viewer/2022042714/5553aa14b4c905d9448b47d5/html5/thumbnails/13.jpg)
*
Simple SR-25 Query
•How many carbs in 1 serving of raw kale?
•Good baby step for food journal
![Page 14: MEAN Stack Workshop at Node Philly, 4/9/14](https://reader034.vdocuments.us/reader034/viewer/2022042714/5553aa14b4c905d9448b47d5/html5/thumbnails/14.jpg)
*
Text Search in MongoDB 2.6
•Don’t want users to have to enter “Kale, raw”
•Example: top 3 results for “grass-fed beef”
![Page 15: MEAN Stack Workshop at Node Philly, 4/9/14](https://reader034.vdocuments.us/reader034/viewer/2022042714/5553aa14b4c905d9448b47d5/html5/thumbnails/15.jpg)
*
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
![Page 16: MEAN Stack Workshop at Node Philly, 4/9/14](https://reader034.vdocuments.us/reader034/viewer/2022042714/5553aa14b4c905d9448b47d5/html5/thumbnails/16.jpg)
*
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
![Page 17: MEAN Stack Workshop at Node Philly, 4/9/14](https://reader034.vdocuments.us/reader034/viewer/2022042714/5553aa14b4c905d9448b47d5/html5/thumbnails/17.jpg)
*
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
![Page 18: MEAN Stack Workshop at Node Philly, 4/9/14](https://reader034.vdocuments.us/reader034/viewer/2022042714/5553aa14b4c905d9448b47d5/html5/thumbnails/18.jpg)
*
passport.json Setup
![Page 19: MEAN Stack Workshop at Node Philly, 4/9/14](https://reader034.vdocuments.us/reader034/viewer/2022042714/5553aa14b4c905d9448b47d5/html5/thumbnails/19.jpg)
*
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
![Page 20: MEAN Stack Workshop at Node Philly, 4/9/14](https://reader034.vdocuments.us/reader034/viewer/2022042714/5553aa14b4c905d9448b47d5/html5/thumbnails/20.jpg)
*
Quick Overview of Mongoose
•ODM for MongoDB and NodeJS
•Schema design and validation
•Convenience objects
•MEAN Stack’s official best friend
![Page 21: MEAN Stack Workshop at Node Philly, 4/9/14](https://reader034.vdocuments.us/reader034/viewer/2022042714/5553aa14b4c905d9448b47d5/html5/thumbnails/21.jpg)
*
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
![Page 22: MEAN Stack Workshop at Node Philly, 4/9/14](https://reader034.vdocuments.us/reader034/viewer/2022042714/5553aa14b4c905d9448b47d5/html5/thumbnails/22.jpg)
*
First, SR-25 Nutrition Item Schema
![Page 23: MEAN Stack Workshop at Node Philly, 4/9/14](https://reader034.vdocuments.us/reader034/viewer/2022042714/5553aa14b4c905d9448b47d5/html5/thumbnails/23.jpg)
*
Having Users is a Positive
![Page 24: MEAN Stack Workshop at Node Philly, 4/9/14](https://reader034.vdocuments.us/reader034/viewer/2022042714/5553aa14b4c905d9448b47d5/html5/thumbnails/24.jpg)
*
Constructing the Day Schema
![Page 25: MEAN Stack Workshop at Node Philly, 4/9/14](https://reader034.vdocuments.us/reader034/viewer/2022042714/5553aa14b4c905d9448b47d5/html5/thumbnails/25.jpg)
*
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
![Page 26: MEAN Stack Workshop at Node Philly, 4/9/14](https://reader034.vdocuments.us/reader034/viewer/2022042714/5553aa14b4c905d9448b47d5/html5/thumbnails/26.jpg)
*
Omni-di to tie this all together
•Avoid dependency hell: don’t require in every file!
![Page 27: MEAN Stack Workshop at Node Philly, 4/9/14](https://reader034.vdocuments.us/reader034/viewer/2022042714/5553aa14b4c905d9448b47d5/html5/thumbnails/27.jpg)
*
Omni-di’s `assemble()` function
![Page 28: MEAN Stack Workshop at Node Philly, 4/9/14](https://reader034.vdocuments.us/reader034/viewer/2022042714/5553aa14b4c905d9448b47d5/html5/thumbnails/28.jpg)
*
Why Two Food Item Services?
Text score sorting in Mongoose, see pull requestWill be fixed in next version of Mongoose!
![Page 29: MEAN Stack Workshop at Node Philly, 4/9/14](https://reader034.vdocuments.us/reader034/viewer/2022042714/5553aa14b4c905d9448b47d5/html5/thumbnails/29.jpg)
*
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!
![Page 30: MEAN Stack Workshop at Node Philly, 4/9/14](https://reader034.vdocuments.us/reader034/viewer/2022042714/5553aa14b4c905d9448b47d5/html5/thumbnails/30.jpg)
*
The API Methods
![Page 31: MEAN Stack Workshop at Node Philly, 4/9/14](https://reader034.vdocuments.us/reader034/viewer/2022042714/5553aa14b4c905d9448b47d5/html5/thumbnails/31.jpg)
*
Search for a Food Item
Note: text search API is atypical, docs here
![Page 32: MEAN Stack Workshop at Node Philly, 4/9/14](https://reader034.vdocuments.us/reader034/viewer/2022042714/5553aa14b4c905d9448b47d5/html5/thumbnails/32.jpg)
*
Load a Day
![Page 33: MEAN Stack Workshop at Node Philly, 4/9/14](https://reader034.vdocuments.us/reader034/viewer/2022042714/5553aa14b4c905d9448b47d5/html5/thumbnails/33.jpg)
*
Save a Day
![Page 34: MEAN Stack Workshop at Node Philly, 4/9/14](https://reader034.vdocuments.us/reader034/viewer/2022042714/5553aa14b4c905d9448b47d5/html5/thumbnails/34.jpg)
*
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`
![Page 35: MEAN Stack Workshop at Node Philly, 4/9/14](https://reader034.vdocuments.us/reader034/viewer/2022042714/5553aa14b4c905d9448b47d5/html5/thumbnails/35.jpg)
*
Step 5: AngularJS + Browserify
•Single Page App: how to manage code bloat?
![Page 36: MEAN Stack Workshop at Node Philly, 4/9/14](https://reader034.vdocuments.us/reader034/viewer/2022042714/5553aa14b4c905d9448b47d5/html5/thumbnails/36.jpg)
*
Browserify = Write Node For Client
•AngularJS dependency in package.json
•Never deal with flakey CDNs again!
![Page 37: MEAN Stack Workshop at Node Philly, 4/9/14](https://reader034.vdocuments.us/reader034/viewer/2022042714/5553aa14b4c905d9448b47d5/html5/thumbnails/37.jpg)
*
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
![Page 38: MEAN Stack Workshop at Node Philly, 4/9/14](https://reader034.vdocuments.us/reader034/viewer/2022042714/5553aa14b4c905d9448b47d5/html5/thumbnails/38.jpg)
*
Single Page App Basics
![Page 39: MEAN Stack Workshop at Node Philly, 4/9/14](https://reader034.vdocuments.us/reader034/viewer/2022042714/5553aa14b4c905d9448b47d5/html5/thumbnails/39.jpg)
*
What index.html Looks Like
ng-view is where the magic happens
![Page 40: MEAN Stack Workshop at Node Philly, 4/9/14](https://reader034.vdocuments.us/reader034/viewer/2022042714/5553aa14b4c905d9448b47d5/html5/thumbnails/40.jpg)
*
http://localhost:3000/#/
![Page 41: MEAN Stack Workshop at Node Philly, 4/9/14](https://reader034.vdocuments.us/reader034/viewer/2022042714/5553aa14b4c905d9448b47d5/html5/thumbnails/41.jpg)
*
http://localhost:3000/#/track
![Page 42: MEAN Stack Workshop at Node Philly, 4/9/14](https://reader034.vdocuments.us/reader034/viewer/2022042714/5553aa14b4c905d9448b47d5/html5/thumbnails/42.jpg)
*
Why Single Page App?
•No server side templating:• Better server throughput
• Cleaner separation of concerns
• Less bandwidth usage
•More control over UX
![Page 43: MEAN Stack Workshop at Node Philly, 4/9/14](https://reader034.vdocuments.us/reader034/viewer/2022042714/5553aa14b4c905d9448b47d5/html5/thumbnails/43.jpg)
*
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
![Page 44: MEAN Stack Workshop at Node Philly, 4/9/14](https://reader034.vdocuments.us/reader034/viewer/2022042714/5553aa14b4c905d9448b47d5/html5/thumbnails/44.jpg)
*
Modifying the AngularJS Module
![Page 45: MEAN Stack Workshop at Node Philly, 4/9/14](https://reader034.vdocuments.us/reader034/viewer/2022042714/5553aa14b4c905d9448b47d5/html5/thumbnails/45.jpg)
*
TrackController Structure
![Page 46: MEAN Stack Workshop at Node Philly, 4/9/14](https://reader034.vdocuments.us/reader034/viewer/2022042714/5553aa14b4c905d9448b47d5/html5/thumbnails/46.jpg)
*
TrackController API
![Page 47: MEAN Stack Workshop at Node Philly, 4/9/14](https://reader034.vdocuments.us/reader034/viewer/2022042714/5553aa14b4c905d9448b47d5/html5/thumbnails/47.jpg)
*
TrackController in the HTML
![Page 48: MEAN Stack Workshop at Node Philly, 4/9/14](https://reader034.vdocuments.us/reader034/viewer/2022042714/5553aa14b4c905d9448b47d5/html5/thumbnails/48.jpg)
*
Implementation of loadDay()
![Page 49: MEAN Stack Workshop at Node Philly, 4/9/14](https://reader034.vdocuments.us/reader034/viewer/2022042714/5553aa14b4c905d9448b47d5/html5/thumbnails/49.jpg)
*
Implementation of recalculate() ?
![Page 50: MEAN Stack Workshop at Node Philly, 4/9/14](https://reader034.vdocuments.us/reader034/viewer/2022042714/5553aa14b4c905d9448b47d5/html5/thumbnails/50.jpg)
*
Code Sharing - calculations.js
![Page 51: MEAN Stack Workshop at Node Philly, 4/9/14](https://reader034.vdocuments.us/reader034/viewer/2022042714/5553aa14b4c905d9448b47d5/html5/thumbnails/51.jpg)
*
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
![Page 52: MEAN Stack Workshop at Node Philly, 4/9/14](https://reader034.vdocuments.us/reader034/viewer/2022042714/5553aa14b4c905d9448b47d5/html5/thumbnails/52.jpg)
*
search() call
![Page 53: MEAN Stack Workshop at Node Philly, 4/9/14](https://reader034.vdocuments.us/reader034/viewer/2022042714/5553aa14b4c905d9448b47d5/html5/thumbnails/53.jpg)
*
addFood() call
![Page 54: MEAN Stack Workshop at Node Philly, 4/9/14](https://reader034.vdocuments.us/reader034/viewer/2022042714/5553aa14b4c905d9448b47d5/html5/thumbnails/54.jpg)
*
Step 7: Unit Testing with Kittens
![Page 55: MEAN Stack Workshop at Node Philly, 4/9/14](https://reader034.vdocuments.us/reader034/viewer/2022042714/5553aa14b4c905d9448b47d5/html5/thumbnails/55.jpg)
*
Get Serious About Testing
•Foundation: proper unit tests, automation
•Heuristic: code “works” iff npm test succeeds
•Grunt or Makefile, either works well
![Page 56: MEAN Stack Workshop at Node Philly, 4/9/14](https://reader034.vdocuments.us/reader034/viewer/2022042714/5553aa14b4c905d9448b47d5/html5/thumbnails/56.jpg)
*
Omni-di and unit tests
•Beauty of DI: easy to control how much to stub
•For unit tests, stub everything
![Page 57: MEAN Stack Workshop at Node Philly, 4/9/14](https://reader034.vdocuments.us/reader034/viewer/2022042714/5553aa14b4c905d9448b47d5/html5/thumbnails/57.jpg)
*
Testing PUT /api/day/:date
![Page 58: MEAN Stack Workshop at Node Philly, 4/9/14](https://reader034.vdocuments.us/reader034/viewer/2022042714/5553aa14b4c905d9448b47d5/html5/thumbnails/58.jpg)
*
Testing PUT /api/day/:date
![Page 59: MEAN Stack Workshop at Node Philly, 4/9/14](https://reader034.vdocuments.us/reader034/viewer/2022042714/5553aa14b4c905d9448b47d5/html5/thumbnails/59.jpg)
*
Testing TrackController
![Page 60: MEAN Stack Workshop at Node Philly, 4/9/14](https://reader034.vdocuments.us/reader034/viewer/2022042714/5553aa14b4c905d9448b47d5/html5/thumbnails/60.jpg)
*
Testing TrackController
![Page 61: MEAN Stack Workshop at Node Philly, 4/9/14](https://reader034.vdocuments.us/reader034/viewer/2022042714/5553aa14b4c905d9448b47d5/html5/thumbnails/61.jpg)
*
Tying Tests Together with make
![Page 62: MEAN Stack Workshop at Node Philly, 4/9/14](https://reader034.vdocuments.us/reader034/viewer/2022042714/5553aa14b4c905d9448b47d5/html5/thumbnails/62.jpg)
*
Browserify SPA Testing Advantages
•Code sharing
•Single test framework - Mocha
![Page 63: MEAN Stack Workshop at Node Philly, 4/9/14](https://reader034.vdocuments.us/reader034/viewer/2022042714/5553aa14b4c905d9448b47d5/html5/thumbnails/63.jpg)
*
Step 8: Authentication
•Last step!
![Page 64: MEAN Stack Workshop at Node Philly, 4/9/14](https://reader034.vdocuments.us/reader034/viewer/2022042714/5553aa14b4c905d9448b47d5/html5/thumbnails/64.jpg)
*
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
![Page 65: MEAN Stack Workshop at Node Philly, 4/9/14](https://reader034.vdocuments.us/reader034/viewer/2022042714/5553aa14b4c905d9448b47d5/html5/thumbnails/65.jpg)
*
Setting up app.js with Passport
![Page 66: MEAN Stack Workshop at Node Philly, 4/9/14](https://reader034.vdocuments.us/reader034/viewer/2022042714/5553aa14b4c905d9448b47d5/html5/thumbnails/66.jpg)
*
checkLogin middleware
![Page 67: MEAN Stack Workshop at Node Philly, 4/9/14](https://reader034.vdocuments.us/reader034/viewer/2022042714/5553aa14b4c905d9448b47d5/html5/thumbnails/67.jpg)
*
checkLogin and TrackController
![Page 68: MEAN Stack Workshop at Node Philly, 4/9/14](https://reader034.vdocuments.us/reader034/viewer/2022042714/5553aa14b4c905d9448b47d5/html5/thumbnails/68.jpg)
*
Passport Setup
![Page 69: MEAN Stack Workshop at Node Philly, 4/9/14](https://reader034.vdocuments.us/reader034/viewer/2022042714/5553aa14b4c905d9448b47d5/html5/thumbnails/69.jpg)
*
Client-side User Tracking
![Page 70: MEAN Stack Workshop at Node Philly, 4/9/14](https://reader034.vdocuments.us/reader034/viewer/2022042714/5553aa14b4c905d9448b47d5/html5/thumbnails/70.jpg)
*
Displaying the Logged In User
![Page 71: MEAN Stack Workshop at Node Philly, 4/9/14](https://reader034.vdocuments.us/reader034/viewer/2022042714/5553aa14b4c905d9448b47d5/html5/thumbnails/71.jpg)
*
Displaying the Logged In User
![Page 72: MEAN Stack Workshop at Node Philly, 4/9/14](https://reader034.vdocuments.us/reader034/viewer/2022042714/5553aa14b4c905d9448b47d5/html5/thumbnails/72.jpg)
*
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
![Page 73: MEAN Stack Workshop at Node Philly, 4/9/14](https://reader034.vdocuments.us/reader034/viewer/2022042714/5553aa14b4c905d9448b47d5/html5/thumbnails/73.jpg)
*
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