73
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

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

Embed Size (px)

Citation preview

Page 1: MEAN Stack Workshop at Node Philly, 4/9/14

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

*

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

*

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

*

What we’re building

Page 5: MEAN Stack Workshop at Node Philly, 4/9/14

*

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

*

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

*

Step by Step, Continued

•Step 7: Unit testing

•Step 8: Authentication

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

*

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

*

What does SR-25 data look like?

Page 11: MEAN Stack Workshop at Node Philly, 4/9/14

*

What Nutrients Look Like

Page 12: MEAN Stack Workshop at Node Philly, 4/9/14

*

What Weights Look Like

Page 13: MEAN Stack Workshop at Node Philly, 4/9/14

*

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

*

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

*

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

*

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

*

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

*

passport.json Setup

Page 19: MEAN Stack Workshop at Node Philly, 4/9/14

*

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

*

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

*

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

*

First, SR-25 Nutrition Item Schema

Page 23: MEAN Stack Workshop at Node Philly, 4/9/14

*

Having Users is a Positive

Page 24: MEAN Stack Workshop at Node Philly, 4/9/14

*

Constructing the Day Schema

Page 25: MEAN Stack Workshop at Node Philly, 4/9/14

*

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

*

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

*

Omni-di’s `assemble()` function

Page 28: MEAN Stack Workshop at Node Philly, 4/9/14

*

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

*

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

*

The API Methods

Page 31: MEAN Stack Workshop at Node Philly, 4/9/14

*

Search for a Food Item

Note: text search API is atypical, docs here

Page 32: MEAN Stack Workshop at Node Philly, 4/9/14

*

Load a Day

Page 33: MEAN Stack Workshop at Node Philly, 4/9/14

*

Save a Day

Page 34: MEAN Stack Workshop at Node Philly, 4/9/14

*

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

*

Step 5: AngularJS + Browserify

•Single Page App: how to manage code bloat?

Page 36: MEAN Stack Workshop at Node Philly, 4/9/14

*

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

*

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

*

Single Page App Basics

Page 39: MEAN Stack Workshop at Node Philly, 4/9/14

*

What index.html Looks Like

ng-view is where the magic happens

Page 40: MEAN Stack Workshop at Node Philly, 4/9/14

*

http://localhost:3000/#/

Page 41: MEAN Stack Workshop at Node Philly, 4/9/14

*

http://localhost:3000/#/track

Page 42: MEAN Stack Workshop at Node Philly, 4/9/14

*

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

*

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

*

Modifying the AngularJS Module

Page 45: MEAN Stack Workshop at Node Philly, 4/9/14

*

TrackController Structure

Page 46: MEAN Stack Workshop at Node Philly, 4/9/14

*

TrackController API

Page 47: MEAN Stack Workshop at Node Philly, 4/9/14

*

TrackController in the HTML

Page 48: MEAN Stack Workshop at Node Philly, 4/9/14

*

Implementation of loadDay()

Page 49: MEAN Stack Workshop at Node Philly, 4/9/14

*

Implementation of recalculate() ?

Page 50: MEAN Stack Workshop at Node Philly, 4/9/14

*

Code Sharing - calculations.js

Page 51: MEAN Stack Workshop at Node Philly, 4/9/14

*

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

*

search() call

Page 53: MEAN Stack Workshop at Node Philly, 4/9/14

*

addFood() call

Page 54: MEAN Stack Workshop at Node Philly, 4/9/14

*

Step 7: Unit Testing with Kittens

Page 55: MEAN Stack Workshop at Node Philly, 4/9/14

*

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

*

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

*

Testing PUT /api/day/:date

Page 58: MEAN Stack Workshop at Node Philly, 4/9/14

*

Testing PUT /api/day/:date

Page 59: MEAN Stack Workshop at Node Philly, 4/9/14

*

Testing TrackController

Page 60: MEAN Stack Workshop at Node Philly, 4/9/14

*

Testing TrackController

Page 61: MEAN Stack Workshop at Node Philly, 4/9/14

*

Tying Tests Together with make

Page 62: MEAN Stack Workshop at Node Philly, 4/9/14

*

Browserify SPA Testing Advantages

•Code sharing

•Single test framework - Mocha

Page 63: MEAN Stack Workshop at Node Philly, 4/9/14

*

Step 8: Authentication

•Last step!

Page 64: MEAN Stack Workshop at Node Philly, 4/9/14

*

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

*

Setting up app.js with Passport

Page 66: MEAN Stack Workshop at Node Philly, 4/9/14

*

checkLogin middleware

Page 67: MEAN Stack Workshop at Node Philly, 4/9/14

*

checkLogin and TrackController

Page 68: MEAN Stack Workshop at Node Philly, 4/9/14

*

Passport Setup

Page 69: MEAN Stack Workshop at Node Philly, 4/9/14

*

Client-side User Tracking

Page 70: MEAN Stack Workshop at Node Philly, 4/9/14

*

Displaying the Logged In User

Page 71: MEAN Stack Workshop at Node Philly, 4/9/14

*

Displaying the Logged In User

Page 72: MEAN Stack Workshop at Node Philly, 4/9/14

*

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