mean stack wenode barcelona workshop
TRANSCRIPT
![Page 1: MEAN Stack WeNode Barcelona Workshop](https://reader033.vdocuments.site/reader033/viewer/2022052508/55935e721a28ab59648b471a/html5/thumbnails/1.jpg)
Guided MEAN Stack Hackathon
Valeri KarpovSoftware Engineer, MongoDBwww.thecodebarbarian.com
www.slideshare.net/vkarpov15github.com/vkarpov15
@code_barbarian
Building (and Testing) a Single Page App in 2 Hours
![Page 2: MEAN Stack WeNode Barcelona Workshop](https://reader033.vdocuments.site/reader033/viewer/2022052508/55935e721a28ab59648b471a/html5/thumbnails/2.jpg)
*
Who is this guy?
•Coined the MEAN stack in April ‘13
•CI/Tools/NodeJS/Go Engineer at MongoDB
•Maintains mongoose, omni-di
•AngularJS since 0.9.4 in 2010
•Hackmaster General at Bookalokal
•Former CTO, LevelUp
![Page 3: MEAN Stack WeNode Barcelona Workshop](https://reader033.vdocuments.site/reader033/viewer/2022052508/55935e721a28ab59648b471a/html5/thumbnails/3.jpg)
*
General Outline
•MEAN = MongoDB, ExpressJS, AngularJS, NodeJS
•Beginner talk: high-level concepts of MEAN
•Emphasis on testing and workflow
•Building a single page app - Axl
•NPM-inspired Package Manager for Golang
•Browser interface only
•No Go knowledge required
![Page 4: MEAN Stack WeNode Barcelona Workshop](https://reader033.vdocuments.site/reader033/viewer/2022052508/55935e721a28ab59648b471a/html5/thumbnails/4.jpg)
*
What You’re Building
![Page 5: MEAN Stack WeNode Barcelona Workshop](https://reader033.vdocuments.site/reader033/viewer/2022052508/55935e721a28ab59648b471a/html5/thumbnails/5.jpg)
*
What You’re Building
•Server for semver-aware package manager
![Page 6: MEAN Stack WeNode Barcelona Workshop](https://reader033.vdocuments.site/reader033/viewer/2022052508/55935e721a28ab59648b471a/html5/thumbnails/6.jpg)
*
Concepts You’ll Be Learning About
•Streams
•API testing
•DOM integration tests with Sauce
•Build systems and architecture
•Configuration + workflow
•General principles for writing NPM packages
![Page 7: MEAN Stack WeNode Barcelona Workshop](https://reader033.vdocuments.site/reader033/viewer/2022052508/55935e721a28ab59648b471a/html5/thumbnails/7.jpg)
*
NPM Packages You’ll Be Using
•mocha: unit tests and API integration tests
•browserify: compile Node JS into browser JS
•mongoose: schema validation for Node + MongoDB
•karma: browser automation for testing
•gulp: general-purpose build workflow
•And several more
![Page 8: MEAN Stack WeNode Barcelona Workshop](https://reader033.vdocuments.site/reader033/viewer/2022052508/55935e721a28ab59648b471a/html5/thumbnails/8.jpg)
*
Step By Step, the Server Side
•Step 1: Define the problem + brief overview of Go
•Step 2: Define schema and models (mongoose)
•Step 3: Build an API (express)
•Step 4: API-level testing (mocha)
•Step 5: Extending the API to support search
![Page 9: MEAN Stack WeNode Barcelona Workshop](https://reader033.vdocuments.site/reader033/viewer/2022052508/55935e721a28ab59648b471a/html5/thumbnails/9.jpg)
*
Step By Step, the HTML Client Side
•Step 6: Create AngularJS SPA client (browserify)
•Step 7: Testing the Single Page App (karma)
•Step 8: CDN for templates and JS (gulp)
![Page 10: MEAN Stack WeNode Barcelona Workshop](https://reader033.vdocuments.site/reader033/viewer/2022052508/55935e721a28ab59648b471a/html5/thumbnails/10.jpg)
*
Step 1: A Brief Overview of Go
•Language developed by Google
•Cute toy language with some niche use cases:• Fast-compiling small native binaries
• Tight integration with C
• “Agent” programs like MongoDB MMS agents
•Has some bad limitations• Generics
• Package management
![Page 11: MEAN Stack WeNode Barcelona Workshop](https://reader033.vdocuments.site/reader033/viewer/2022052508/55935e721a28ab59648b471a/html5/thumbnails/11.jpg)
*
Hello, World in Go
![Page 12: MEAN Stack WeNode Barcelona Workshop](https://reader033.vdocuments.site/reader033/viewer/2022052508/55935e721a28ab59648b471a/html5/thumbnails/12.jpg)
*
Why Build a Go Package Manager
•npm gets package management mostly right
•Go doesn’t and could use some help
![Page 13: MEAN Stack WeNode Barcelona Workshop](https://reader033.vdocuments.site/reader033/viewer/2022052508/55935e721a28ab59648b471a/html5/thumbnails/13.jpg)
*
What npm Does Right
•Mostly semantic versioning (no v20130722)• Will my code break if I upgrade from v2.1.3 to v2.1.4?
•2 commands to install and test• npm install
• npm test
• And you’re ready to hack
•No need to change PATH or env variables
•Result: a package for every use case
•Go doesn’t have any of this
![Page 14: MEAN Stack WeNode Barcelona Workshop](https://reader033.vdocuments.site/reader033/viewer/2022052508/55935e721a28ab59648b471a/html5/thumbnails/14.jpg)
*
Goals for Axl Server
•Upload/download releases of projects
•Projects hosted on Amazon Cloudfront (streams!)
•Query for projects using semver syntax:• version 1.2.0 matches “~1.2”, “>=1.2.0”, “<=1.3.0”, etc.
• Thankfully, there’s an npm module for that
•Ability to search projects by keyword
•Sane build system and workflow
•Take advantage of a single page app
![Page 15: MEAN Stack WeNode Barcelona Workshop](https://reader033.vdocuments.site/reader033/viewer/2022052508/55935e721a28ab59648b471a/html5/thumbnails/15.jpg)
*
Step 2: Design Schemas
“Smart data structures and dumb code works a lot better than the other way around.”
- Eric S. Raymond
“Bad programmers worry about the code. Good programmers worry about data structures and their relationships.”
- Linus Torvalds
![Page 16: MEAN Stack WeNode Barcelona Workshop](https://reader033.vdocuments.site/reader033/viewer/2022052508/55935e721a28ab59648b471a/html5/thumbnails/16.jpg)
*
A Brief Overview of Mongoose
•MongoDB is schema-less
•But your schema design still matters!
•Mongoose = NodeJS schemas for MongoDB• Validation
• Casting for objects and queries
• Promises and other syntactic sugar
• Object document mapper (ODM)
•Users include Tinder and McDonalds
![Page 17: MEAN Stack WeNode Barcelona Workshop](https://reader033.vdocuments.site/reader033/viewer/2022052508/55935e721a28ab59648b471a/html5/thumbnails/17.jpg)
*
Simple Example: A User Schema
![Page 18: MEAN Stack WeNode Barcelona Workshop](https://reader033.vdocuments.site/reader033/viewer/2022052508/55935e721a28ab59648b471a/html5/thumbnails/18.jpg)
*
Model = Schema + DB Connection
![Page 19: MEAN Stack WeNode Barcelona Workshop](https://reader033.vdocuments.site/reader033/viewer/2022052508/55935e721a28ab59648b471a/html5/thumbnails/19.jpg)
*
About the User Model
•_id and username will be pulled from Twitter oauth
•Most real data will be tracked in other models
![Page 20: MEAN Stack WeNode Barcelona Workshop](https://reader033.vdocuments.site/reader033/viewer/2022052508/55935e721a28ab59648b471a/html5/thumbnails/20.jpg)
*
The Project Schema
•In Go, project names are strings like “github.com/vkarpov15/mgo”
•Releases a list of semver strings
![Page 21: MEAN Stack WeNode Barcelona Workshop](https://reader033.vdocuments.site/reader033/viewer/2022052508/55935e721a28ab59648b471a/html5/thumbnails/21.jpg)
*
Why the data Field?
•Simple and intuitive access control
•data contains fields user can edit
![Page 22: MEAN Stack WeNode Barcelona Workshop](https://reader033.vdocuments.site/reader033/viewer/2022052508/55935e721a28ab59648b471a/html5/thumbnails/22.jpg)
*
Project Schema Indexes
•MongoDB has indexes for speeding up queries
•Tradeoffs: may make writes slower
•Project schema indexes on:• Project name
• Maintainers usernames (multi-key!)
• Name and keywords text index (more in search section)
![Page 23: MEAN Stack WeNode Barcelona Workshop](https://reader033.vdocuments.site/reader033/viewer/2022052508/55935e721a28ab59648b471a/html5/thumbnails/23.jpg)
*
The Release Schema
•Semver release of a project (with download info)
![Page 24: MEAN Stack WeNode Barcelona Workshop](https://reader033.vdocuments.site/reader033/viewer/2022052508/55935e721a28ab59648b471a/html5/thumbnails/24.jpg)
*
Validators in Mongoose
•validate ensures name exists and version is valid semver
![Page 25: MEAN Stack WeNode Barcelona Workshop](https://reader033.vdocuments.site/reader033/viewer/2022052508/55935e721a28ab59648b471a/html5/thumbnails/25.jpg)
*
Virtuals in Mongoose
•stringify can be accessed as a property
![Page 26: MEAN Stack WeNode Barcelona Workshop](https://reader033.vdocuments.site/reader033/viewer/2022052508/55935e721a28ab59648b471a/html5/thumbnails/26.jpg)
*
Indexes for Release Schema
•Indexes can be ordered to help with sorting
•The -1 means higher releaseNumbers come first
•Indexes define how you’ll query your data
![Page 27: MEAN Stack WeNode Barcelona Workshop](https://reader033.vdocuments.site/reader033/viewer/2022052508/55935e721a28ab59648b471a/html5/thumbnails/27.jpg)
*
Last Schema: DownloadHistory
•Because you want to highlight popular packages
![Page 28: MEAN Stack WeNode Barcelona Workshop](https://reader033.vdocuments.site/reader033/viewer/2022052508/55935e721a28ab59648b471a/html5/thumbnails/28.jpg)
*
DownloadHistory Indexes
•For the two common use cases of DownloadHistory• How many downloads did a package have this month?
• What are the most popular packages this month?
![Page 29: MEAN Stack WeNode Barcelona Workshop](https://reader033.vdocuments.site/reader033/viewer/2022052508/55935e721a28ab59648b471a/html5/thumbnails/29.jpg)
*
Schema Design Takeaways
•Design schemas carefully
•Use indexes that fit your use cases
•Don’t go overboard on indexing everything!
•Use Mongoose for seamless validation + casting
![Page 30: MEAN Stack WeNode Barcelona Workshop](https://reader033.vdocuments.site/reader033/viewer/2022052508/55935e721a28ab59648b471a/html5/thumbnails/30.jpg)
*
Step 3: REST-ish API with Express
•Express: powerful lightweight web framework
•Highly customizable (> 6900 packages on npm)
•Rapidly growing user base:• NBC
• SegmentIO
• MySpace
![Page 31: MEAN Stack WeNode Barcelona Workshop](https://reader033.vdocuments.site/reader033/viewer/2022052508/55935e721a28ab59648b471a/html5/thumbnails/31.jpg)
*
Whats in an API?
•API = actions on top of objects
•REST principles: use HTTP error codes and verbs
•Key concerns for API scalability:• Load search results piece-by-piece from DB
• Hit indexes
• Don’t preclude horizontal scalability (multiple servers)
•MEAN stack allows you to be very lazy
![Page 32: MEAN Stack WeNode Barcelona Workshop](https://reader033.vdocuments.site/reader033/viewer/2022052508/55935e721a28ab59648b471a/html5/thumbnails/32.jpg)
*
API Basics: Load a Project By Name
•GET /api/project?project=gopkg.in/mgo
![Page 33: MEAN Stack WeNode Barcelona Workshop](https://reader033.vdocuments.site/reader033/viewer/2022052508/55935e721a28ab59648b471a/html5/thumbnails/33.jpg)
*
A Slide Dedicated to a Bad Pun
•Only place where Axl can tolerate a Slash :)•(Slash was the guitarist for GNR. He and Axl don’t like each other)
![Page 34: MEAN Stack WeNode Barcelona Workshop](https://reader033.vdocuments.site/reader033/viewer/2022052508/55935e721a28ab59648b471a/html5/thumbnails/34.jpg)
*
Brief Aside on Dependency Injection
•Using my lightweight DI helper, omni-di
•Tool for managing and constructing dependencies
•Create objects once, pass them in to functions
•Injector inspects parameter names to find correct dependencies
![Page 35: MEAN Stack WeNode Barcelona Workshop](https://reader033.vdocuments.site/reader033/viewer/2022052508/55935e721a28ab59648b471a/html5/thumbnails/35.jpg)
*
Brief Aside on Dependency Injection
![Page 36: MEAN Stack WeNode Barcelona Workshop](https://reader033.vdocuments.site/reader033/viewer/2022052508/55935e721a28ab59648b471a/html5/thumbnails/36.jpg)
*
Routes With Dependency Injection
![Page 37: MEAN Stack WeNode Barcelona Workshop](https://reader033.vdocuments.site/reader033/viewer/2022052508/55935e721a28ab59648b471a/html5/thumbnails/37.jpg)
*
Using the Express Router
![Page 38: MEAN Stack WeNode Barcelona Workshop](https://reader033.vdocuments.site/reader033/viewer/2022052508/55935e721a28ab59648b471a/html5/thumbnails/38.jpg)
*
Filling out the Project API
![Page 39: MEAN Stack WeNode Barcelona Workshop](https://reader033.vdocuments.site/reader033/viewer/2022052508/55935e721a28ab59648b471a/html5/thumbnails/39.jpg)
*
Brief Aside: Authentication
•Twitter Oauth with redirect
•Passport: Express-compatible login middleware
![Page 40: MEAN Stack WeNode Barcelona Workshop](https://reader033.vdocuments.site/reader033/viewer/2022052508/55935e721a28ab59648b471a/html5/thumbnails/40.jpg)
*
Brief Aside: Authentication
![Page 41: MEAN Stack WeNode Barcelona Workshop](https://reader033.vdocuments.site/reader033/viewer/2022052508/55935e721a28ab59648b471a/html5/thumbnails/41.jpg)
*
POST = Create a Project
•POST /api/project - Mongoose is magical
![Page 42: MEAN Stack WeNode Barcelona Workshop](https://reader033.vdocuments.site/reader033/viewer/2022052508/55935e721a28ab59648b471a/html5/thumbnails/42.jpg)
*
PUT = Modify an Existing Project
![Page 43: MEAN Stack WeNode Barcelona Workshop](https://reader033.vdocuments.site/reader033/viewer/2022052508/55935e721a28ab59648b471a/html5/thumbnails/43.jpg)
*
More Sophisticated: Semver Query
•Find me a Release that matches “~1.2”
•GET /api/release?project=gopkg.in/mgo&version=~1.2
•Perfect application of streams
•Hard to index semver queries
![Page 44: MEAN Stack WeNode Barcelona Workshop](https://reader033.vdocuments.site/reader033/viewer/2022052508/55935e721a28ab59648b471a/html5/thumbnails/44.jpg)
*
More Sophisticated: Semver Query
![Page 45: MEAN Stack WeNode Barcelona Workshop](https://reader033.vdocuments.site/reader033/viewer/2022052508/55935e721a28ab59648b471a/html5/thumbnails/45.jpg)
*
Streaming Document by Document
•Like a for loop, but don’t load whole array in RAM
![Page 46: MEAN Stack WeNode Barcelona Workshop](https://reader033.vdocuments.site/reader033/viewer/2022052508/55935e721a28ab59648b471a/html5/thumbnails/46.jpg)
*
And If You Don’t Find a Document...
•Return a nice, handy 404
![Page 47: MEAN Stack WeNode Barcelona Workshop](https://reader033.vdocuments.site/reader033/viewer/2022052508/55935e721a28ab59648b471a/html5/thumbnails/47.jpg)
*
POST /api/release
•The most important and most sophisticated
•Subtleties:• Race conditions between multiple servers
• Error handling
• CDN (or, why the “scale npm” campaign happened)
• Authorization
![Page 48: MEAN Stack WeNode Barcelona Workshop](https://reader033.vdocuments.site/reader033/viewer/2022052508/55935e721a28ab59648b471a/html5/thumbnails/48.jpg)
*
Pushing a new Release
•POST /api/release?project=gopkg.in/mgo&version=1.2.0
![Page 49: MEAN Stack WeNode Barcelona Workshop](https://reader033.vdocuments.site/reader033/viewer/2022052508/55935e721a28ab59648b471a/html5/thumbnails/49.jpg)
*
MongoDB for Multi-server Concurrency
•MongoDB operations are ACID per document
•ACID stands for• Atomic
• Consistent
• Isolated
• Durable
•FindAndModify underlies Mongoose findOneAndUpdate()
![Page 50: MEAN Stack WeNode Barcelona Workshop](https://reader033.vdocuments.site/reader033/viewer/2022052508/55935e721a28ab59648b471a/html5/thumbnails/50.jpg)
*
Multi-Server POST /api/release
•findOneAndUpdate is ACID means a version gets added to a project only once
•Multiple servers => only one wins
![Page 51: MEAN Stack WeNode Barcelona Workshop](https://reader033.vdocuments.site/reader033/viewer/2022052508/55935e721a28ab59648b471a/html5/thumbnails/51.jpg)
*
The isNew Flag
•isNew = false means “return document before update”
![Page 52: MEAN Stack WeNode Barcelona Workshop](https://reader033.vdocuments.site/reader033/viewer/2022052508/55935e721a28ab59648b471a/html5/thumbnails/52.jpg)
*
POST /api/release Checks, Part 1
![Page 53: MEAN Stack WeNode Barcelona Workshop](https://reader033.vdocuments.site/reader033/viewer/2022052508/55935e721a28ab59648b471a/html5/thumbnails/53.jpg)
*
POST /api/release Checks, Part 2
•Check if release existed before findOneAndUpdate
•If so, return handy conflict error
![Page 54: MEAN Stack WeNode Barcelona Workshop](https://reader033.vdocuments.site/reader033/viewer/2022052508/55935e721a28ab59648b471a/html5/thumbnails/54.jpg)
*
Pushing To Amazon S3
•Easy to set up Cloudfront on top of Amazon S3
•Node lets you stream files to S3
•No more worrying about server HD space
![Page 55: MEAN Stack WeNode Barcelona Workshop](https://reader033.vdocuments.site/reader033/viewer/2022052508/55935e721a28ab59648b471a/html5/thumbnails/55.jpg)
*
Pushing To Amazon S3
![Page 56: MEAN Stack WeNode Barcelona Workshop](https://reader033.vdocuments.site/reader033/viewer/2022052508/55935e721a28ab59648b471a/html5/thumbnails/56.jpg)
*
Using PipeToS3
![Page 57: MEAN Stack WeNode Barcelona Workshop](https://reader033.vdocuments.site/reader033/viewer/2022052508/55935e721a28ab59648b471a/html5/thumbnails/57.jpg)
*
Step 3: Testing the API
•Writing API is easy, testing can be hard
•But easy with Express + Mocha + Node!
•Stub out authentication
•Event-driven nature of JS: no interrupts
•Single process responsible for:• Running Express server
• Sending HTTP requests to Express server
• Using Mocha to test the results of HTTP requests
![Page 58: MEAN Stack WeNode Barcelona Workshop](https://reader033.vdocuments.site/reader033/viewer/2022052508/55935e721a28ab59648b471a/html5/thumbnails/58.jpg)
*
Step 4: Testing the API
•Writing API is easy, testing can be hard
•But easy with Express + Mocha + Node!
•Stub out authentication
•Event-driven nature of JS: no interrupts
•Single process responsible for:• Running Express server
• Sending HTTP requests to Express server
• Using Mocha to test the results of HTTP requests
![Page 59: MEAN Stack WeNode Barcelona Workshop](https://reader033.vdocuments.site/reader033/viewer/2022052508/55935e721a28ab59648b471a/html5/thumbnails/59.jpg)
*
Why One Process?
•Minimal setup
•Run tests with one command
•Use real configuration
•Can assert on state of DB as well as result
![Page 60: MEAN Stack WeNode Barcelona Workshop](https://reader033.vdocuments.site/reader033/viewer/2022052508/55935e721a28ab59648b471a/html5/thumbnails/60.jpg)
*
High Level Mocha Structure
![Page 61: MEAN Stack WeNode Barcelona Workshop](https://reader033.vdocuments.site/reader033/viewer/2022052508/55935e721a28ab59648b471a/html5/thumbnails/61.jpg)
*
General Idea for Release API Tests
![Page 62: MEAN Stack WeNode Barcelona Workshop](https://reader033.vdocuments.site/reader033/viewer/2022052508/55935e721a28ab59648b471a/html5/thumbnails/62.jpg)
*
First Case: Load Exact Version
![Page 63: MEAN Stack WeNode Barcelona Workshop](https://reader033.vdocuments.site/reader033/viewer/2022052508/55935e721a28ab59648b471a/html5/thumbnails/63.jpg)
*
Test Loading Version with Semver
![Page 64: MEAN Stack WeNode Barcelona Workshop](https://reader033.vdocuments.site/reader033/viewer/2022052508/55935e721a28ab59648b471a/html5/thumbnails/64.jpg)
*
Test Uploading a Release
![Page 65: MEAN Stack WeNode Barcelona Workshop](https://reader033.vdocuments.site/reader033/viewer/2022052508/55935e721a28ab59648b471a/html5/thumbnails/65.jpg)
*
Testing Workflow
•Systems like Gulp are sometimes overkill
•Don’t ask people to “npm install mocha -g”!• Version management
• Incompatibilities with different projects versions
• Breaks the npm install promise
![Page 66: MEAN Stack WeNode Barcelona Workshop](https://reader033.vdocuments.site/reader033/viewer/2022052508/55935e721a28ab59648b471a/html5/thumbnails/66.jpg)
*
Using Makefile for Testing
•Makefile surprisingly common in NodeJS
•Usually as a command shortener
•Use “make api-test” to run tests
![Page 67: MEAN Stack WeNode Barcelona Workshop](https://reader033.vdocuments.site/reader033/viewer/2022052508/55935e721a28ab59648b471a/html5/thumbnails/67.jpg)
*
Brief Demo of Tests
![Page 68: MEAN Stack WeNode Barcelona Workshop](https://reader033.vdocuments.site/reader033/viewer/2022052508/55935e721a28ab59648b471a/html5/thumbnails/68.jpg)
*
Step 5: Search API
•Use testing framework to do some TDD
•Test-driven Development: tests first, then code
•Usually done with unit tests
•Faster and more fun with API integration tests
![Page 69: MEAN Stack WeNode Barcelona Workshop](https://reader033.vdocuments.site/reader033/viewer/2022052508/55935e721a28ab59648b471a/html5/thumbnails/69.jpg)
*
TDD First Step
![Page 70: MEAN Stack WeNode Barcelona Workshop](https://reader033.vdocuments.site/reader033/viewer/2022052508/55935e721a28ab59648b471a/html5/thumbnails/70.jpg)
*
Assumptions from Test
•GET /api/search?q=test
•Search project name and keywords
•Return list of projects in JSON
![Page 71: MEAN Stack WeNode Barcelona Workshop](https://reader033.vdocuments.site/reader033/viewer/2022052508/55935e721a28ab59648b471a/html5/thumbnails/71.jpg)
*
MongoDB Text Search
•Introduced in MongoDB 2.6 (beta feature in 2.4)
•Does exactly what this search API needs
•First need to create a text index
![Page 72: MEAN Stack WeNode Barcelona Workshop](https://reader033.vdocuments.site/reader033/viewer/2022052508/55935e721a28ab59648b471a/html5/thumbnails/72.jpg)
*
Filling Out The Search API
![Page 73: MEAN Stack WeNode Barcelona Workshop](https://reader033.vdocuments.site/reader033/viewer/2022052508/55935e721a28ab59648b471a/html5/thumbnails/73.jpg)
*
Notes on Text Search
•Requires mongoose >= 3.8.9
•The $meta keyword used to get “text score”
•Higher text score => more relevant
•Usually want to sort by text result
•Supports stemming in 15 languages
![Page 74: MEAN Stack WeNode Barcelona Workshop](https://reader033.vdocuments.site/reader033/viewer/2022052508/55935e721a28ab59648b471a/html5/thumbnails/74.jpg)
*
What is Stemming?
![Page 75: MEAN Stack WeNode Barcelona Workshop](https://reader033.vdocuments.site/reader033/viewer/2022052508/55935e721a28ab59648b471a/html5/thumbnails/75.jpg)
*
What is Stemming?
•“Test” matches both “test” and “testing”
![Page 76: MEAN Stack WeNode Barcelona Workshop](https://reader033.vdocuments.site/reader033/viewer/2022052508/55935e721a28ab59648b471a/html5/thumbnails/76.jpg)
*
Step 6: AngularJS SPA Client
•REST API is only the beginning
•What about building a client?
•AngularJS is the best tool for the job (IMO)• MVC-ish client-side templating framework
• Two-way data binding
• Dependency injection, elegant structure
•Writing client-side JS is painful - use Browserify
•Won’t need very sophisticated AngularJS for Axl
![Page 77: MEAN Stack WeNode Barcelona Workshop](https://reader033.vdocuments.site/reader033/viewer/2022052508/55935e721a28ab59648b471a/html5/thumbnails/77.jpg)
*
Book Announcement
•My book on AngularJS is coming out Dec 22
•Pre-order on Amazon for a more detailed dive into AngularJS
![Page 78: MEAN Stack WeNode Barcelona Workshop](https://reader033.vdocuments.site/reader033/viewer/2022052508/55935e721a28ab59648b471a/html5/thumbnails/78.jpg)
*
Overview of AngularJS
•Client-side templates (Two-way data binding)
•Client-side routing (Single Page Apps)
![Page 79: MEAN Stack WeNode Barcelona Workshop](https://reader033.vdocuments.site/reader033/viewer/2022052508/55935e721a28ab59648b471a/html5/thumbnails/79.jpg)
*
Why a Single Page App?
•Clean separation of data and views
•Ship HTML separately from data
•Enables you to store HTML as static asset (Cloudfront)
•Leaves your server free to serve up JSON
•Cleaner separation of concerns
![Page 80: MEAN Stack WeNode Barcelona Workshop](https://reader033.vdocuments.site/reader033/viewer/2022052508/55935e721a28ab59648b471a/html5/thumbnails/80.jpg)
*
Overview of Browserify
•Compiles NodeJS JS into one browser-friendly file
•Use same dependencies on client and server:• moment
• underscore
• mongoose (schemas + validation only)
• other isomorphic JS
•Easy to upload JS to Cloudfront as static asset
![Page 81: MEAN Stack WeNode Barcelona Workshop](https://reader033.vdocuments.site/reader033/viewer/2022052508/55935e721a28ab59648b471a/html5/thumbnails/81.jpg)
*
Using AngularJS and Browserify
•npm has an angular package
•Only includes “core angular”
•You may still need other packages
![Page 82: MEAN Stack WeNode Barcelona Workshop](https://reader033.vdocuments.site/reader033/viewer/2022052508/55935e721a28ab59648b471a/html5/thumbnails/82.jpg)
*
Word of Warning
•npm angular package depends on contextify
•Contextify is notoriously picky about install reqs
•You need right version of python and a C++ compiler
•Possible, but tricky, to install on Windows
•I prefer to list angular as a devDependency in package.json
![Page 83: MEAN Stack WeNode Barcelona Workshop](https://reader033.vdocuments.site/reader033/viewer/2022052508/55935e721a28ab59648b471a/html5/thumbnails/83.jpg)
*
Writing AngularJS in NodeJS
•Create an AngularJS “module”
•Axl also needs the angular client-side routing module
![Page 84: MEAN Stack WeNode Barcelona Workshop](https://reader033.vdocuments.site/reader033/viewer/2022052508/55935e721a28ab59648b471a/html5/thumbnails/84.jpg)
*
Setting up Client Side Routing
![Page 85: MEAN Stack WeNode Barcelona Workshop](https://reader033.vdocuments.site/reader033/viewer/2022052508/55935e721a28ab59648b471a/html5/thumbnails/85.jpg)
*
How Client-Side Routing Works
•Only modify hash portion of the URL
![Page 86: MEAN Stack WeNode Barcelona Workshop](https://reader033.vdocuments.site/reader033/viewer/2022052508/55935e721a28ab59648b471a/html5/thumbnails/86.jpg)
*
What Does a Template Look Like?
•Written in Jade:
•“ng-” and “{{ }}” are tie-ins to AngularJS
![Page 87: MEAN Stack WeNode Barcelona Workshop](https://reader033.vdocuments.site/reader033/viewer/2022052508/55935e721a28ab59648b471a/html5/thumbnails/87.jpg)
*
Ok, So What’s a Controller?
•Defines an in-HTML API for the template to use
•Responsible for loading and organizing data
•Attaches properties to template “scope”
![Page 88: MEAN Stack WeNode Barcelona Workshop](https://reader033.vdocuments.site/reader033/viewer/2022052508/55935e721a28ab59648b471a/html5/thumbnails/88.jpg)
*
And What’s $projects?
•A service
•Typically a convenience wrapper around a resource loaded from the server
![Page 89: MEAN Stack WeNode Barcelona Workshop](https://reader033.vdocuments.site/reader033/viewer/2022052508/55935e721a28ab59648b471a/html5/thumbnails/89.jpg)
*
How Do Controllers and Services Get Added to AngularJS?
![Page 90: MEAN Stack WeNode Barcelona Workshop](https://reader033.vdocuments.site/reader033/viewer/2022052508/55935e721a28ab59648b471a/html5/thumbnails/90.jpg)
*
Compiling with Browserify
•Output ./bin/javascript/ui.js with all JavaScript
![Page 91: MEAN Stack WeNode Barcelona Workshop](https://reader033.vdocuments.site/reader033/viewer/2022052508/55935e721a28ab59648b471a/html5/thumbnails/91.jpg)
*
Using Compiled JS
•In base jade file, layout.jade, include ui.js:
•Browserify downside: need to compile before use
![Page 92: MEAN Stack WeNode Barcelona Workshop](https://reader033.vdocuments.site/reader033/viewer/2022052508/55935e721a28ab59648b471a/html5/thumbnails/92.jpg)
*
Compiling Templates
•Jade downside: need to compile to HTML
•Jade has significant upsides over static HTML:• Readability
• Can include conditionals on server configuration
• Handy for testing - next section
•So we also need to compile Jade!
![Page 93: MEAN Stack WeNode Barcelona Workshop](https://reader033.vdocuments.site/reader033/viewer/2022052508/55935e721a28ab59648b471a/html5/thumbnails/93.jpg)
*
Why Compile Templates
•Jade downside: need to compile to HTML
•Jade has significant upsides over static HTML:• Readability
• Can include conditionals on server configuration
• Handy for testing - next section
•So we also need to compile Jade!
![Page 94: MEAN Stack WeNode Barcelona Workshop](https://reader033.vdocuments.site/reader033/viewer/2022052508/55935e721a28ab59648b471a/html5/thumbnails/94.jpg)
*
Idea For Compiling Jade
![Page 95: MEAN Stack WeNode Barcelona Workshop](https://reader033.vdocuments.site/reader033/viewer/2022052508/55935e721a28ab59648b471a/html5/thumbnails/95.jpg)
*
Compiling Templates Wrapup
•AngularJS templates need to be HTML
•Very easy to compile Jade
•Take advantage of server configuration
![Page 96: MEAN Stack WeNode Barcelona Workshop](https://reader033.vdocuments.site/reader033/viewer/2022052508/55935e721a28ab59648b471a/html5/thumbnails/96.jpg)
*
Step 7: Testing the AngularJS Client
•Trickiest part of any project: users will run your code in different OS, browser, machine, etc.
•My job at MongoDB = this for the mongodb server
•Great tools for this in web-dev world:• Sauce: think Amazon EC2 for browsers
• Karma: Popular browser automation tool
• ngScenario: AngularJS E2E testing framework
![Page 97: MEAN Stack WeNode Barcelona Workshop](https://reader033.vdocuments.site/reader033/viewer/2022052508/55935e721a28ab59648b471a/html5/thumbnails/97.jpg)
*
DOM Integration Tests
•Test the whole browser side of your code
•That is, test AngularJS’ integration with the DOM
•Stub out REST API calls (speed and ease of setup)
•Setting up data for E2E tests is often complex
•Sometimes known as a “midway test”
![Page 98: MEAN Stack WeNode Barcelona Workshop](https://reader033.vdocuments.site/reader033/viewer/2022052508/55935e721a28ab59648b471a/html5/thumbnails/98.jpg)
*
Karma Overview
•Interface for launching a browser and running tests
•Rich set of plugins
•Handles tunneling for remote browsers
•Plugins for launching• local browsers (chrome, firefox, IE, etc.)
• browsers in the Sauce cloud
•My answer to “if I were stuck on a desert island with only one npm module”
![Page 99: MEAN Stack WeNode Barcelona Workshop](https://reader033.vdocuments.site/reader033/viewer/2022052508/55935e721a28ab59648b471a/html5/thumbnails/99.jpg)
*
Tradeoffs, Local vs Sauce
•I recommend doing both
•Sauce allows you to spawn any browser:• Chrome on Linux
• IE6 on WinXP
• Android 4.3 (yes, mobile included)
•But is slow and flakey
•Local is difficult to set up, but:• Easier to debug: you can actually see the tests run
• Fast and reliable
![Page 100: MEAN Stack WeNode Barcelona Workshop](https://reader033.vdocuments.site/reader033/viewer/2022052508/55935e721a28ab59648b471a/html5/thumbnails/100.jpg)
*
Workflow and Local vs Sauce
•Make sure tests run with local config on Chrome
•Then use Sauce to run tests on different browsers
•Karma makes this easy: different configs
![Page 101: MEAN Stack WeNode Barcelona Workshop](https://reader033.vdocuments.site/reader033/viewer/2022052508/55935e721a28ab59648b471a/html5/thumbnails/101.jpg)
*
Karma Plugin Ecosystem
•Karma itself is a lightweight core
•Need plugins to make it do anything useful
•Yet another npm package with its own npm package ecosystem (~170 plugins)
![Page 102: MEAN Stack WeNode Barcelona Workshop](https://reader033.vdocuments.site/reader033/viewer/2022052508/55935e721a28ab59648b471a/html5/thumbnails/102.jpg)
*
Generating a Karma Config
•Karma configs are pretty straightforward
•Karma has some handy tools:
• “node_modules/karma/bin/karma init” creates a new config after asking you a few questions
•Or just copy/paste examples
![Page 103: MEAN Stack WeNode Barcelona Workshop](https://reader033.vdocuments.site/reader033/viewer/2022052508/55935e721a28ab59648b471a/html5/thumbnails/103.jpg)
*
Local Karma Config for Axl
![Page 104: MEAN Stack WeNode Barcelona Workshop](https://reader033.vdocuments.site/reader033/viewer/2022052508/55935e721a28ab59648b471a/html5/thumbnails/104.jpg)
*
Sauce Karma Config - Browser List
![Page 105: MEAN Stack WeNode Barcelona Workshop](https://reader033.vdocuments.site/reader033/viewer/2022052508/55935e721a28ab59648b471a/html5/thumbnails/105.jpg)
*
Sauce Karma Config - The Rest
![Page 106: MEAN Stack WeNode Barcelona Workshop](https://reader033.vdocuments.site/reader033/viewer/2022052508/55935e721a28ab59648b471a/html5/thumbnails/106.jpg)
*
Karma Sauce Environment Vars
•karma-sauce-launcher relies on 2 env variables:• SAUCE_USERNAME: your Sauce username
• SAUCE_ACCESS_KEY: Sauce API key
•Make sure these are set or your tests will fail
![Page 107: MEAN Stack WeNode Barcelona Workshop](https://reader033.vdocuments.site/reader033/viewer/2022052508/55935e721a28ab59648b471a/html5/thumbnails/107.jpg)
*
Writing the Actual DOM Tests
![Page 108: MEAN Stack WeNode Barcelona Workshop](https://reader033.vdocuments.site/reader033/viewer/2022052508/55935e721a28ab59648b471a/html5/thumbnails/108.jpg)
*
Couple Words of Warning
•The api() function is home-baked
•The AngularJS equivalent, $httpBackend, is weird
•More about $httpBackend in Chapter 9 of Professional AngularJS :)
•ngScenario is quirky and technically deprecated
•Its replacement, Protractor, is more quirky and doesn’t support DOM integration tests
![Page 109: MEAN Stack WeNode Barcelona Workshop](https://reader033.vdocuments.site/reader033/viewer/2022052508/55935e721a28ab59648b471a/html5/thumbnails/109.jpg)
*
How Does the API Function Work?
•ngScenario DSL: domain specific language
![Page 110: MEAN Stack WeNode Barcelona Workshop](https://reader033.vdocuments.site/reader033/viewer/2022052508/55935e721a28ab59648b471a/html5/thumbnails/110.jpg)
*
window.AxlAPI
•Use a different layout.jade for running tests:• Don’t load bootstrap
• Expose methods to stub out API requests
•ngScenario runs your tests in an iframe, so it can actually interact with the code under test
![Page 111: MEAN Stack WeNode Barcelona Workshop](https://reader033.vdocuments.site/reader033/viewer/2022052508/55935e721a28ab59648b471a/html5/thumbnails/111.jpg)
*
window.AxlAPI
![Page 112: MEAN Stack WeNode Barcelona Workshop](https://reader033.vdocuments.site/reader033/viewer/2022052508/55935e721a28ab59648b471a/html5/thumbnails/112.jpg)
*
Makefile Rules for Running Tests
•Remember, need env vars for Sauce tests
![Page 113: MEAN Stack WeNode Barcelona Workshop](https://reader033.vdocuments.site/reader033/viewer/2022052508/55935e721a28ab59648b471a/html5/thumbnails/113.jpg)
*
Demo of Running DOM Tests
![Page 114: MEAN Stack WeNode Barcelona Workshop](https://reader033.vdocuments.site/reader033/viewer/2022052508/55935e721a28ab59648b471a/html5/thumbnails/114.jpg)
*
Step 8: Deploying to S3 with Gulp
•With SPA, your HTML is static
•Might as well push it out to a CDN
•Last step, stay focused!
![Page 115: MEAN Stack WeNode Barcelona Workshop](https://reader033.vdocuments.site/reader033/viewer/2022052508/55935e721a28ab59648b471a/html5/thumbnails/115.jpg)
*
Overview of Gulp
•Simple build tool for web apps
•Another core package with a lot of plugins
•Grunt is its more well-known competitor
•Advantage of Gulp: its plain NodeJS
•List tasks in gulpfile.js
•Re-use your existing code and use streams!
![Page 116: MEAN Stack WeNode Barcelona Workshop](https://reader033.vdocuments.site/reader033/viewer/2022052508/55935e721a28ab59648b471a/html5/thumbnails/116.jpg)
*
Including Gulp in package.json
![Page 117: MEAN Stack WeNode Barcelona Workshop](https://reader033.vdocuments.site/reader033/viewer/2022052508/55935e721a28ab59648b471a/html5/thumbnails/117.jpg)
*
Minifying JS with Gulp
![Page 118: MEAN Stack WeNode Barcelona Workshop](https://reader033.vdocuments.site/reader033/viewer/2022052508/55935e721a28ab59648b471a/html5/thumbnails/118.jpg)
*
Uploading to S3 with Gulp Overview
![Page 119: MEAN Stack WeNode Barcelona Workshop](https://reader033.vdocuments.site/reader033/viewer/2022052508/55935e721a28ab59648b471a/html5/thumbnails/119.jpg)
*
Uploading Templates to S3 with Gulp
![Page 120: MEAN Stack WeNode Barcelona Workshop](https://reader033.vdocuments.site/reader033/viewer/2022052508/55935e721a28ab59648b471a/html5/thumbnails/120.jpg)
*
Configuring AngularJS to Load Templates Remotely
![Page 121: MEAN Stack WeNode Barcelona Workshop](https://reader033.vdocuments.site/reader033/viewer/2022052508/55935e721a28ab59648b471a/html5/thumbnails/121.jpg)
*
Configuring Jade to Load Templates Remotely
![Page 122: MEAN Stack WeNode Barcelona Workshop](https://reader033.vdocuments.site/reader033/viewer/2022052508/55935e721a28ab59648b471a/html5/thumbnails/122.jpg)
*
And the End Result
![Page 123: MEAN Stack WeNode Barcelona Workshop](https://reader033.vdocuments.site/reader033/viewer/2022052508/55935e721a28ab59648b471a/html5/thumbnails/123.jpg)
*
And that’s a wrap! Time to Review
•Single page app with MEAN stack
•Mongoose Schema
•Express API
•AngularJS routing
•Browserify for building client code
•Karma for testing
•Gulp for pushing HTML+JS to S3+Cloudfront
![Page 124: MEAN Stack WeNode Barcelona Workshop](https://reader033.vdocuments.site/reader033/viewer/2022052508/55935e721a28ab59648b471a/html5/thumbnails/124.jpg)
*
Thanks for Listening!
•Slides on:• Twitter: @code_barbarian
• Slideshare: slideshare.net/vkarpov15
•Repo on github: https://github.com/vkarpov15/axl-server
•Professional AngularJS on Amazon