SlideShare una empresa de Scribd logo
1 de 30
Descargar para leer sin conexión
Node.js in Production
at Aviary
NYC Node.js Meetup
March 5, 2014
Aviary
Photo-Editing
SDK & Apps
Fully-Baked UI
Configurable, High-Quality Tools
Over 6,500 Partners
Over 70 Million Monthly Users
Over 6 Billion Photos Edited
iOS, Android, Web, Server
J
Who Are We?
Nir

Jack

Lead Serverside

Director of

Engineer

Engineering

Likes:
●
●
●

Automated deployment
Big-O notation
Brainteasers

Hates:
●

Cilantro

Likes:
●
●
●

Parallelizing processes
DRY code
Seltzer

Hates:
●

Food after the sell-by date
Who Are We?
Jeff

Ari

Serverside

Developer

Engineer

Evangelist

Likes:
●
●
●

Performance Profiling
Spaces, not tabs
Bikes

Hates:
●

His Photo

Likes:
●
●
●

Empowering Developers
Refactoring/Patterns
Dancing

Hates:
●

Forrest Gump
How Do We Use Node?
● In Production:
○
○
○
○
○

● Future:

Analytics Dashboard
○ Server-side Rendering API
Content Delivery (CDS) ○ Automated billing
Public Website
Receipts Collection
Monitoring Tools
Why Do We Use Node?
●
●
●
●
●
●
●
●

Extremely fast and lightweight
Easy to iterate on
Common language for client and server
JSON
Cross Platform
npm
express module
Active Community
Setting Up
Your Server
Request Routing
Our API servers all require(routes.json)
{
“home”: {
“getVersion”: {
“verb”: “get”,
“path”: “/version”
}
},
“queue”: {
“updateContent”: {
“verb”: ”put”,
“path”: “/content/:id”,
“permissions”: [“content”]
}
}
}

for (var controllerName in routes) {
var controller = require(ctrlrDir + controllerName);
for (var endpointName in routes[controllerName]) {
var endpoint =
routes[controllerName][endpointName];
var callback = controller[endpointName];
app[endpoint.verb](
endpoint.path,
ensurePermissions(endpoint.permissions),
callback
);
}
}
Authentication: Overview
Request

Server
listens

Middleware

Logged in?

No
Yes

Response

Request handler takes
over

Does user have
permission?

Redirected to login
page

Authenticated user
saved in cookie
Authentication: Login
passport.use(new GoogleStrategy({ returnURL: DOMAIN + '/auth/return' },
function (identifier, profile, done) {
var userInfo = {
name: profile.email.value,
fullName: profile.name
};
userRepository.findUserByName(userInfo.name, function (findErr, foundUser) {
// ...
if (foundUser.length === 0) {
done('Invalid user', null);
return;
}
userInfo.userId = foundUser.user_id;
userInfo.permissions = foundUser.permissions;
done(null, userInfo);
});
}
));
Working with
JSON
Validation - JSON Schema
SCHEMA

● JSON-based

JSON

{

{
“type”: “object”
“additionalProperties”: false
“properties”: {
“status”: {
“type”: “string”,
“enum”: [“ok”, “error”],
“required”: true
},
“data”: {
“type”: “object”,
“required”: false
}
}

● Like XML Schema
● Validation modules
● Used throughout
Aviary’s systems

}

“status”: “ok”
}
{
“status”: “error”,
“data”: {
“reason”: “hoisting”
}
}
{
“status”: “gladys”,
“node”: “meetup”
}
Advanced JSON - Content
Effects

Frames

Stickers

Messages
The One-To-Many Problem
Android expects responses to look like this:
iOS 1.0 expects responses to look like this:
iOS 2.0 expects responses to look like this:
Response Formatting - The Model
Content Entry

Response Formats

Responses

JSON document describing
content item

JSON documents defining mappings
from entry to responses

Actual JSON responses
delivered to devices
Response Formatting - Details
The Single Content Entry
"identifier": "com.aviary.stickers.234fe"

The Response Format
"id": {

"dataKey": "identifier"

"icon": {
"path": "cds/hats/icon.png"
"path-100": "cds/hats/icon100.png"

},
"isPaid": {

"isPaid": true,
"iconImagePath": "cds/hats/icon100.png"
"stickers": [
{

"type": "boolean",

},

"dataKey": "isFree",

{

"identifier": "1"

"transformations": ["negateBool"]

"items": [

"imageUrl": "cds/hats/1.png"

},

"identifier": "1"

}

"iconImagePath": {

"imageUrl": "cds/hats/1.png"

"type": "string",

}
]

"id": "com.aviary.stickers.234fe",
"type": "string",

"isFree": false,

The Response

"dataKey": "icon.path-100"
},
"stickers": {
"type": "array",
"dataKey": "items"

]
Code Sample (Dumbed Down)
var formattedResponse = {};

for (var propName in responseFormat) {
var val = contentEntry[responseFormat[propName].dataKey];
for (var transformation in responseFormat[propName].transformations) {
val = transformationModule[transformation](val);
}
formattedResponse[propName] = val;
}

return formattedResponse;
Interacting with
External Processes
Image Rendering
Challenge: Use our existing image rendering .NET/C++
process from node server
Solution:
require(‘child_process’).spawn(‘renderer.exe’)

Benefits: Easy IPC, asynchronous workflow
Code Sample
var spawn = require(‘child_process’).spawn;

var renderer = spawn(‘renderer.exe’, [‘-i’, ‘inputImage.jpg’, … ]);
// read text
renderer.stderr.setEncoding(‘utf8’);
renderer.stderr.on(‘data’, function (data) { json += data; });
// or binary data
renderer.stdout.on(‘data’, function (data) { buffers.push(data); });

renderer.on(‘close’, function (code, signal) {
// respond to exit code, signal (e.g. ‘SIGTERM’), process output
var diagnostics = JSON.parse(json);
var img = Buffer.concat(buffers);
});
Going Live
Testing Philosophy
● Unit tests (sparingly)
● End-to-end integration tests
● Mocha
● Enforced before push
○ (master / development)
Example Integration Test
#!/bin/bash

● Bash script

mocha scopecreation &&
mocha cmsformatcreation &&
mocha crfcreation &&

● Independent files

mocha mrfcreation &&
mocha rflcreation &&
mocha appcreation &&

● Shared configuration

mocha contentcreation &&
mocha manifestcreation &&
mocha push &&

● Single failure stops
process

mocha cmsformatupdate &&
mocha crfaddition &&
mocha rfladdition &&
mocha contentupdate &&
mocha manifestupdate
Automated Deployment: Overview
Git

S3
2) Jenkins
polls for repo
changes

1) Code is
pushed to
master

3) Code is zipped
and uploaded to S3

Jenkins
4) Get a list of
live servers in
this group

AWS API

5) SSH into each
server and run
the bootstrap script
Automated Deployment: Bootstrap
5) SSH into each
server and run
the bootstrap script

#!/bin/bash
ZIP_LOCATION="s3://aviary/projectX/deployment.zip";
cd ~/projectX;
sudo apt-get -y -q install nodejs@0.10.0;
sudo apt-get -y -q install s3cmd;
sudo npm install -g forever@0.10.8;

Goals of the bootstrap.sh:
1. Ensure all dependencies are
installed
2. Download and extract project
3. Ensure HTTP traffic is routed to the
proper port
4. Keep the old version of the project
live until the moment the new one is
ready to go live

# Missing step: create s3 configuration file
s3cmd -c /usr/local/s3cfg.config get "$ZIP_LOCATION" theCds.zip;
unzip -q -o deployment.zip
iptables -t nat -A PREROUTING -p tcp --dport 80 -j
REDIRECT --to-ports 8142;
forever stopall;
forever start server.js;
Summary
Lessons Learned (1)
● Integration tests!
● Watch out for node and npm updates
○ Hardcode the node version you’re using
○ If you’re using package.json, version everything
● Node.js + MongoDb are a great couple
● Make sure you understand hoisting
Lessons Learned (2)
● Always callback in async functions
● Always return after a callback
● Node doesn’t always run the same on all platforms
● Use middleware only when necessary
● Always store dates as Unix Timestamps
○ Timezones are a pain in your future
● Throwing unhandled errors will crash your process
Conclusion
Today, our production node servers:
● serve dynamic content to 20MM people (soon 70MM)
● power our website: aviary.com
● log real-time receipt data for every in-app purchase
● allow us to analyze hundreds of millions of events daily
● power quick scripts and one-off internal tools
Questions?
Comments also welcome
nir@aviary.com - jack@aviary.com - ari@aviary.com - jeff@aviary.com
…and by the way, WE’RE HIRING!

Más contenido relacionado

La actualidad más candente

Angular 6 - The Complete Guide
Angular 6 - The Complete GuideAngular 6 - The Complete Guide
Angular 6 - The Complete GuideSam Dias
 
React App State Management with react hooks and context api
React App State Management with react hooks and context apiReact App State Management with react hooks and context api
React App State Management with react hooks and context apiJan Ranostaj
 
Introduction To Angular 4 - J2I
Introduction To Angular 4 - J2IIntroduction To Angular 4 - J2I
Introduction To Angular 4 - J2INader Debbabi
 
Angular%201%20to%20angular%202
Angular%201%20to%20angular%202Angular%201%20to%20angular%202
Angular%201%20to%20angular%202Ran Wahle
 
Angular 10 course_content
Angular 10 course_contentAngular 10 course_content
Angular 10 course_contentNAVEENSAGGAM1
 
Building scalable modular app with Angular2 concept
Building scalable modular app with Angular2 conceptBuilding scalable modular app with Angular2 concept
Building scalable modular app with Angular2 conceptkzw
 
Introduction to Angular 2
Introduction to Angular 2Introduction to Angular 2
Introduction to Angular 2Naveen Pete
 
Angular App Presentation
Angular App PresentationAngular App Presentation
Angular App PresentationElizabeth Long
 
Routing & Navigating Pages in Angular 2
Routing & Navigating Pages in Angular 2Routing & Navigating Pages in Angular 2
Routing & Navigating Pages in Angular 2Knoldus Inc.
 
Mastering angular - Dot Net Tricks
Mastering angular - Dot Net TricksMastering angular - Dot Net Tricks
Mastering angular - Dot Net TricksGaurav Singh
 
Angular2 + Ng-Lightning + Lightning Design System = Great Apps
Angular2 + Ng-Lightning + Lightning Design System = Great AppsAngular2 + Ng-Lightning + Lightning Design System = Great Apps
Angular2 + Ng-Lightning + Lightning Design System = Great AppsEmily Hurn
 
Dependency Injection pattern in Angular
Dependency Injection pattern in AngularDependency Injection pattern in Angular
Dependency Injection pattern in AngularAlexe Bogdan
 
From React to React Native - Things I wish I knew when I started
From React to React Native - Things I wish I knew when I startedFrom React to React Native - Things I wish I knew when I started
From React to React Native - Things I wish I knew when I startedsparkfabrik
 
Developing a Demo Application with Angular 4 - J2I
Developing a Demo Application with Angular 4 - J2IDeveloping a Demo Application with Angular 4 - J2I
Developing a Demo Application with Angular 4 - J2INader Debbabi
 
What’s new in angular 12[highlights of angular 12 features]
What’s new in angular 12[highlights of angular 12 features]What’s new in angular 12[highlights of angular 12 features]
What’s new in angular 12[highlights of angular 12 features]Katy Slemon
 
OCTO BOF - How to build Netvibes with AngularJS
OCTO BOF - How to build Netvibes with AngularJSOCTO BOF - How to build Netvibes with AngularJS
OCTO BOF - How to build Netvibes with AngularJSJonathan Meiss
 
Introduction to angular 2
Introduction to angular 2Introduction to angular 2
Introduction to angular 2Dor Moshe
 

La actualidad más candente (20)

Angular 6 - The Complete Guide
Angular 6 - The Complete GuideAngular 6 - The Complete Guide
Angular 6 - The Complete Guide
 
React App State Management with react hooks and context api
React App State Management with react hooks and context apiReact App State Management with react hooks and context api
React App State Management with react hooks and context api
 
Angular 2
Angular 2Angular 2
Angular 2
 
Introduction To Angular 4 - J2I
Introduction To Angular 4 - J2IIntroduction To Angular 4 - J2I
Introduction To Angular 4 - J2I
 
Angular 4 - quick view
Angular 4 - quick viewAngular 4 - quick view
Angular 4 - quick view
 
Angular%201%20to%20angular%202
Angular%201%20to%20angular%202Angular%201%20to%20angular%202
Angular%201%20to%20angular%202
 
Angular 10 course_content
Angular 10 course_contentAngular 10 course_content
Angular 10 course_content
 
Building scalable modular app with Angular2 concept
Building scalable modular app with Angular2 conceptBuilding scalable modular app with Angular2 concept
Building scalable modular app with Angular2 concept
 
Introduction to Angular 2
Introduction to Angular 2Introduction to Angular 2
Introduction to Angular 2
 
Angular App Presentation
Angular App PresentationAngular App Presentation
Angular App Presentation
 
Angular 2
Angular 2Angular 2
Angular 2
 
Routing & Navigating Pages in Angular 2
Routing & Navigating Pages in Angular 2Routing & Navigating Pages in Angular 2
Routing & Navigating Pages in Angular 2
 
Mastering angular - Dot Net Tricks
Mastering angular - Dot Net TricksMastering angular - Dot Net Tricks
Mastering angular - Dot Net Tricks
 
Angular2 + Ng-Lightning + Lightning Design System = Great Apps
Angular2 + Ng-Lightning + Lightning Design System = Great AppsAngular2 + Ng-Lightning + Lightning Design System = Great Apps
Angular2 + Ng-Lightning + Lightning Design System = Great Apps
 
Dependency Injection pattern in Angular
Dependency Injection pattern in AngularDependency Injection pattern in Angular
Dependency Injection pattern in Angular
 
From React to React Native - Things I wish I knew when I started
From React to React Native - Things I wish I knew when I startedFrom React to React Native - Things I wish I knew when I started
From React to React Native - Things I wish I knew when I started
 
Developing a Demo Application with Angular 4 - J2I
Developing a Demo Application with Angular 4 - J2IDeveloping a Demo Application with Angular 4 - J2I
Developing a Demo Application with Angular 4 - J2I
 
What’s new in angular 12[highlights of angular 12 features]
What’s new in angular 12[highlights of angular 12 features]What’s new in angular 12[highlights of angular 12 features]
What’s new in angular 12[highlights of angular 12 features]
 
OCTO BOF - How to build Netvibes with AngularJS
OCTO BOF - How to build Netvibes with AngularJSOCTO BOF - How to build Netvibes with AngularJS
OCTO BOF - How to build Netvibes with AngularJS
 
Introduction to angular 2
Introduction to angular 2Introduction to angular 2
Introduction to angular 2
 

Destacado

Running Node.js in Production using Passenger
Running Node.js in Production using PassengerRunning Node.js in Production using Passenger
Running Node.js in Production using Passengerdavidchubbs
 
Node JS (Francisco Cerdas)
Node JS (Francisco Cerdas)Node JS (Francisco Cerdas)
Node JS (Francisco Cerdas)PiXeL16
 
Investigacion de aviary
Investigacion de aviaryInvestigacion de aviary
Investigacion de aviaryJulio Alvarez
 
Building a real life application in node js
Building a real life application in node jsBuilding a real life application in node js
Building a real life application in node jsfakedarren
 
Nodifying the Enterprise - Prince Soni, TO THE NEW
Nodifying the Enterprise - Prince Soni, TO THE NEWNodifying the Enterprise - Prince Soni, TO THE NEW
Nodifying the Enterprise - Prince Soni, TO THE NEWNodejsFoundation
 
Gestión Básica de la Información
Gestión Básica de la InformaciónGestión Básica de la Información
Gestión Básica de la InformaciónJuan Carlos Quinche
 
It is not supposed to fly but it does
It is not supposed to fly but it doesIt is not supposed to fly but it does
It is not supposed to fly but it doesGabriele Lana
 
Anatomy of a Modern Node.js Application Architecture
Anatomy of a Modern Node.js Application Architecture Anatomy of a Modern Node.js Application Architecture
Anatomy of a Modern Node.js Application Architecture AppDynamics
 
Nodejs Explained with Examples
Nodejs Explained with ExamplesNodejs Explained with Examples
Nodejs Explained with ExamplesGabriele Lana
 
Introduction to Node.js
Introduction to Node.jsIntroduction to Node.js
Introduction to Node.jsVikash Singh
 
Node Foundation Membership Overview 20160907
Node Foundation Membership Overview 20160907Node Foundation Membership Overview 20160907
Node Foundation Membership Overview 20160907NodejsFoundation
 

Destacado (15)

Running Node.js in Production using Passenger
Running Node.js in Production using PassengerRunning Node.js in Production using Passenger
Running Node.js in Production using Passenger
 
Node JS (Francisco Cerdas)
Node JS (Francisco Cerdas)Node JS (Francisco Cerdas)
Node JS (Francisco Cerdas)
 
Investigacion de aviary
Investigacion de aviaryInvestigacion de aviary
Investigacion de aviary
 
Aviary
AviaryAviary
Aviary
 
Node.js
Node.jsNode.js
Node.js
 
Introducción a Node.js
Introducción a Node.jsIntroducción a Node.js
Introducción a Node.js
 
Building a real life application in node js
Building a real life application in node jsBuilding a real life application in node js
Building a real life application in node js
 
Aviaries
AviariesAviaries
Aviaries
 
Nodifying the Enterprise - Prince Soni, TO THE NEW
Nodifying the Enterprise - Prince Soni, TO THE NEWNodifying the Enterprise - Prince Soni, TO THE NEW
Nodifying the Enterprise - Prince Soni, TO THE NEW
 
Gestión Básica de la Información
Gestión Básica de la InformaciónGestión Básica de la Información
Gestión Básica de la Información
 
It is not supposed to fly but it does
It is not supposed to fly but it doesIt is not supposed to fly but it does
It is not supposed to fly but it does
 
Anatomy of a Modern Node.js Application Architecture
Anatomy of a Modern Node.js Application Architecture Anatomy of a Modern Node.js Application Architecture
Anatomy of a Modern Node.js Application Architecture
 
Nodejs Explained with Examples
Nodejs Explained with ExamplesNodejs Explained with Examples
Nodejs Explained with Examples
 
Introduction to Node.js
Introduction to Node.jsIntroduction to Node.js
Introduction to Node.js
 
Node Foundation Membership Overview 20160907
Node Foundation Membership Overview 20160907Node Foundation Membership Overview 20160907
Node Foundation Membership Overview 20160907
 

Similar a Node in Production at Aviary

Content Delivery at Aviary - NYC MUG 11/19/13
Content Delivery at Aviary - NYC MUG 11/19/13Content Delivery at Aviary - NYC MUG 11/19/13
Content Delivery at Aviary - NYC MUG 11/19/13MongoDB
 
MongoDB and Content Delivery at Aviary by Nir Zicherman and Jack Sisson
MongoDB and Content Delivery at Aviary by Nir Zicherman and Jack SissonMongoDB and Content Delivery at Aviary by Nir Zicherman and Jack Sisson
MongoDB and Content Delivery at Aviary by Nir Zicherman and Jack SissonHakka Labs
 
Parse cloud code
Parse cloud codeParse cloud code
Parse cloud code維佋 唐
 
Exploring Google (Cloud) APIs with Python & JavaScript
Exploring Google (Cloud) APIs with Python & JavaScriptExploring Google (Cloud) APIs with Python & JavaScript
Exploring Google (Cloud) APIs with Python & JavaScriptwesley chun
 
Kandroid for nhn_deview_20131013_v5_final
Kandroid for nhn_deview_20131013_v5_finalKandroid for nhn_deview_20131013_v5_final
Kandroid for nhn_deview_20131013_v5_finalNAVER D2
 
Building production-quality apps with Node.js
Building production-quality apps with Node.jsBuilding production-quality apps with Node.js
Building production-quality apps with Node.jsmattpardee
 
Frontend APIs powering fast paced product iterations
Frontend APIs powering fast paced product iterationsFrontend APIs powering fast paced product iterations
Frontend APIs powering fast paced product iterationsKarthik Ramgopal
 
I Just Want to Run My Code: Waypoint, Nomad, and Other Things
I Just Want to Run My Code: Waypoint, Nomad, and Other ThingsI Just Want to Run My Code: Waypoint, Nomad, and Other Things
I Just Want to Run My Code: Waypoint, Nomad, and Other ThingsMichael Lange
 
Introduction to Cloud Computing with Google Cloud
Introduction to Cloud Computing with Google CloudIntroduction to Cloud Computing with Google Cloud
Introduction to Cloud Computing with Google Cloudwesley chun
 
Using Google (Cloud) APIs
Using Google (Cloud) APIsUsing Google (Cloud) APIs
Using Google (Cloud) APIswesley chun
 
Modern Web Applications Utilizing HTML5 (Dev Con TLV 06-2013)
Modern Web Applications Utilizing HTML5 (Dev Con TLV 06-2013)Modern Web Applications Utilizing HTML5 (Dev Con TLV 06-2013)
Modern Web Applications Utilizing HTML5 (Dev Con TLV 06-2013)Ido Green
 
Cross Platform Mobile App Development
Cross Platform Mobile App DevelopmentCross Platform Mobile App Development
Cross Platform Mobile App DevelopmentAnnmarie Lanesey
 
Alfresco Development Framework Basic
Alfresco Development Framework BasicAlfresco Development Framework Basic
Alfresco Development Framework BasicMario Romano
 
viWave Study Group - Introduction to Google Android Development - Chapter 23 ...
viWave Study Group - Introduction to Google Android Development - Chapter 23 ...viWave Study Group - Introduction to Google Android Development - Chapter 23 ...
viWave Study Group - Introduction to Google Android Development - Chapter 23 ...Ted Chien
 
Future of Development and Deployment using Docker
Future of Development and Deployment using DockerFuture of Development and Deployment using Docker
Future of Development and Deployment using DockerTamer Abdul-Radi
 
Designing flexible apps deployable to App Engine, Cloud Functions, or Cloud Run
Designing flexible apps deployable to App Engine, Cloud Functions, or Cloud RunDesigning flexible apps deployable to App Engine, Cloud Functions, or Cloud Run
Designing flexible apps deployable to App Engine, Cloud Functions, or Cloud Runwesley chun
 
Playing with parse.com
Playing with parse.comPlaying with parse.com
Playing with parse.comJUG Genova
 
Utilizing HTML5 APIs
Utilizing HTML5 APIsUtilizing HTML5 APIs
Utilizing HTML5 APIsIdo Green
 

Similar a Node in Production at Aviary (20)

Content Delivery at Aviary - NYC MUG 11/19/13
Content Delivery at Aviary - NYC MUG 11/19/13Content Delivery at Aviary - NYC MUG 11/19/13
Content Delivery at Aviary - NYC MUG 11/19/13
 
MongoDB and Content Delivery at Aviary by Nir Zicherman and Jack Sisson
MongoDB and Content Delivery at Aviary by Nir Zicherman and Jack SissonMongoDB and Content Delivery at Aviary by Nir Zicherman and Jack Sisson
MongoDB and Content Delivery at Aviary by Nir Zicherman and Jack Sisson
 
Parse cloud code
Parse cloud codeParse cloud code
Parse cloud code
 
Exploring Google (Cloud) APIs with Python & JavaScript
Exploring Google (Cloud) APIs with Python & JavaScriptExploring Google (Cloud) APIs with Python & JavaScript
Exploring Google (Cloud) APIs with Python & JavaScript
 
Kandroid for nhn_deview_20131013_v5_final
Kandroid for nhn_deview_20131013_v5_finalKandroid for nhn_deview_20131013_v5_final
Kandroid for nhn_deview_20131013_v5_final
 
Nativescript with angular 2
Nativescript with angular 2Nativescript with angular 2
Nativescript with angular 2
 
Building production-quality apps with Node.js
Building production-quality apps with Node.jsBuilding production-quality apps with Node.js
Building production-quality apps with Node.js
 
Frontend APIs powering fast paced product iterations
Frontend APIs powering fast paced product iterationsFrontend APIs powering fast paced product iterations
Frontend APIs powering fast paced product iterations
 
I Just Want to Run My Code: Waypoint, Nomad, and Other Things
I Just Want to Run My Code: Waypoint, Nomad, and Other ThingsI Just Want to Run My Code: Waypoint, Nomad, and Other Things
I Just Want to Run My Code: Waypoint, Nomad, and Other Things
 
Introduction to Cloud Computing with Google Cloud
Introduction to Cloud Computing with Google CloudIntroduction to Cloud Computing with Google Cloud
Introduction to Cloud Computing with Google Cloud
 
Using Google (Cloud) APIs
Using Google (Cloud) APIsUsing Google (Cloud) APIs
Using Google (Cloud) APIs
 
Modern Web Applications Utilizing HTML5 (Dev Con TLV 06-2013)
Modern Web Applications Utilizing HTML5 (Dev Con TLV 06-2013)Modern Web Applications Utilizing HTML5 (Dev Con TLV 06-2013)
Modern Web Applications Utilizing HTML5 (Dev Con TLV 06-2013)
 
Cross Platform Mobile App Development
Cross Platform Mobile App DevelopmentCross Platform Mobile App Development
Cross Platform Mobile App Development
 
Alfresco Development Framework Basic
Alfresco Development Framework BasicAlfresco Development Framework Basic
Alfresco Development Framework Basic
 
viWave Study Group - Introduction to Google Android Development - Chapter 23 ...
viWave Study Group - Introduction to Google Android Development - Chapter 23 ...viWave Study Group - Introduction to Google Android Development - Chapter 23 ...
viWave Study Group - Introduction to Google Android Development - Chapter 23 ...
 
Nodejs
NodejsNodejs
Nodejs
 
Future of Development and Deployment using Docker
Future of Development and Deployment using DockerFuture of Development and Deployment using Docker
Future of Development and Deployment using Docker
 
Designing flexible apps deployable to App Engine, Cloud Functions, or Cloud Run
Designing flexible apps deployable to App Engine, Cloud Functions, or Cloud RunDesigning flexible apps deployable to App Engine, Cloud Functions, or Cloud Run
Designing flexible apps deployable to App Engine, Cloud Functions, or Cloud Run
 
Playing with parse.com
Playing with parse.comPlaying with parse.com
Playing with parse.com
 
Utilizing HTML5 APIs
Utilizing HTML5 APIsUtilizing HTML5 APIs
Utilizing HTML5 APIs
 

Último

The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxLoriGlavin3
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteDianaGray10
 
What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024Stephanie Beckett
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek SchlawackFwdays
 
Moving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfMoving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfLoriGlavin3
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenHervé Boutemy
 
Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Mattias Andersson
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsSergiu Bodiu
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .Alan Dix
 
unit 4 immunoblotting technique complete.pptx
unit 4 immunoblotting technique complete.pptxunit 4 immunoblotting technique complete.pptx
unit 4 immunoblotting technique complete.pptxBkGupta21
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr BaganFwdays
 
SAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxSAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxNavinnSomaal
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brandgvaughan
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
SALESFORCE EDUCATION CLOUD | FEXLE SERVICES
SALESFORCE EDUCATION CLOUD | FEXLE SERVICESSALESFORCE EDUCATION CLOUD | FEXLE SERVICES
SALESFORCE EDUCATION CLOUD | FEXLE SERVICESmohitsingh558521
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxLoriGlavin3
 
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024BookNet Canada
 
What is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfWhat is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfMounikaPolabathina
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfAlex Barbosa Coqueiro
 

Último (20)

The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptx
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test Suite
 
What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
 
Moving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfMoving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdf
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache Maven
 
Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platforms
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .
 
unit 4 immunoblotting technique complete.pptx
unit 4 immunoblotting technique complete.pptxunit 4 immunoblotting technique complete.pptx
unit 4 immunoblotting technique complete.pptx
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan
 
SAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxSAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptx
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brand
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
SALESFORCE EDUCATION CLOUD | FEXLE SERVICES
SALESFORCE EDUCATION CLOUD | FEXLE SERVICESSALESFORCE EDUCATION CLOUD | FEXLE SERVICES
SALESFORCE EDUCATION CLOUD | FEXLE SERVICES
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
 
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
 
What is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfWhat is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdf
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdf
 

Node in Production at Aviary

  • 1. Node.js in Production at Aviary NYC Node.js Meetup March 5, 2014
  • 2. Aviary Photo-Editing SDK & Apps Fully-Baked UI Configurable, High-Quality Tools Over 6,500 Partners Over 70 Million Monthly Users Over 6 Billion Photos Edited iOS, Android, Web, Server J
  • 3. Who Are We? Nir Jack Lead Serverside Director of Engineer Engineering Likes: ● ● ● Automated deployment Big-O notation Brainteasers Hates: ● Cilantro Likes: ● ● ● Parallelizing processes DRY code Seltzer Hates: ● Food after the sell-by date
  • 4. Who Are We? Jeff Ari Serverside Developer Engineer Evangelist Likes: ● ● ● Performance Profiling Spaces, not tabs Bikes Hates: ● His Photo Likes: ● ● ● Empowering Developers Refactoring/Patterns Dancing Hates: ● Forrest Gump
  • 5. How Do We Use Node? ● In Production: ○ ○ ○ ○ ○ ● Future: Analytics Dashboard ○ Server-side Rendering API Content Delivery (CDS) ○ Automated billing Public Website Receipts Collection Monitoring Tools
  • 6. Why Do We Use Node? ● ● ● ● ● ● ● ● Extremely fast and lightweight Easy to iterate on Common language for client and server JSON Cross Platform npm express module Active Community
  • 8. Request Routing Our API servers all require(routes.json) { “home”: { “getVersion”: { “verb”: “get”, “path”: “/version” } }, “queue”: { “updateContent”: { “verb”: ”put”, “path”: “/content/:id”, “permissions”: [“content”] } } } for (var controllerName in routes) { var controller = require(ctrlrDir + controllerName); for (var endpointName in routes[controllerName]) { var endpoint = routes[controllerName][endpointName]; var callback = controller[endpointName]; app[endpoint.verb]( endpoint.path, ensurePermissions(endpoint.permissions), callback ); } }
  • 9. Authentication: Overview Request Server listens Middleware Logged in? No Yes Response Request handler takes over Does user have permission? Redirected to login page Authenticated user saved in cookie
  • 10. Authentication: Login passport.use(new GoogleStrategy({ returnURL: DOMAIN + '/auth/return' }, function (identifier, profile, done) { var userInfo = { name: profile.email.value, fullName: profile.name }; userRepository.findUserByName(userInfo.name, function (findErr, foundUser) { // ... if (foundUser.length === 0) { done('Invalid user', null); return; } userInfo.userId = foundUser.user_id; userInfo.permissions = foundUser.permissions; done(null, userInfo); }); } ));
  • 12. Validation - JSON Schema SCHEMA ● JSON-based JSON { { “type”: “object” “additionalProperties”: false “properties”: { “status”: { “type”: “string”, “enum”: [“ok”, “error”], “required”: true }, “data”: { “type”: “object”, “required”: false } } ● Like XML Schema ● Validation modules ● Used throughout Aviary’s systems } “status”: “ok” } { “status”: “error”, “data”: { “reason”: “hoisting” } } { “status”: “gladys”, “node”: “meetup” }
  • 13. Advanced JSON - Content Effects Frames Stickers Messages
  • 14. The One-To-Many Problem Android expects responses to look like this: iOS 1.0 expects responses to look like this: iOS 2.0 expects responses to look like this:
  • 15. Response Formatting - The Model Content Entry Response Formats Responses JSON document describing content item JSON documents defining mappings from entry to responses Actual JSON responses delivered to devices
  • 16. Response Formatting - Details The Single Content Entry "identifier": "com.aviary.stickers.234fe" The Response Format "id": { "dataKey": "identifier" "icon": { "path": "cds/hats/icon.png" "path-100": "cds/hats/icon100.png" }, "isPaid": { "isPaid": true, "iconImagePath": "cds/hats/icon100.png" "stickers": [ { "type": "boolean", }, "dataKey": "isFree", { "identifier": "1" "transformations": ["negateBool"] "items": [ "imageUrl": "cds/hats/1.png" }, "identifier": "1" } "iconImagePath": { "imageUrl": "cds/hats/1.png" "type": "string", } ] "id": "com.aviary.stickers.234fe", "type": "string", "isFree": false, The Response "dataKey": "icon.path-100" }, "stickers": { "type": "array", "dataKey": "items" ]
  • 17. Code Sample (Dumbed Down) var formattedResponse = {}; for (var propName in responseFormat) { var val = contentEntry[responseFormat[propName].dataKey]; for (var transformation in responseFormat[propName].transformations) { val = transformationModule[transformation](val); } formattedResponse[propName] = val; } return formattedResponse;
  • 19. Image Rendering Challenge: Use our existing image rendering .NET/C++ process from node server Solution: require(‘child_process’).spawn(‘renderer.exe’) Benefits: Easy IPC, asynchronous workflow
  • 20. Code Sample var spawn = require(‘child_process’).spawn; var renderer = spawn(‘renderer.exe’, [‘-i’, ‘inputImage.jpg’, … ]); // read text renderer.stderr.setEncoding(‘utf8’); renderer.stderr.on(‘data’, function (data) { json += data; }); // or binary data renderer.stdout.on(‘data’, function (data) { buffers.push(data); }); renderer.on(‘close’, function (code, signal) { // respond to exit code, signal (e.g. ‘SIGTERM’), process output var diagnostics = JSON.parse(json); var img = Buffer.concat(buffers); });
  • 22. Testing Philosophy ● Unit tests (sparingly) ● End-to-end integration tests ● Mocha ● Enforced before push ○ (master / development)
  • 23. Example Integration Test #!/bin/bash ● Bash script mocha scopecreation && mocha cmsformatcreation && mocha crfcreation && ● Independent files mocha mrfcreation && mocha rflcreation && mocha appcreation && ● Shared configuration mocha contentcreation && mocha manifestcreation && mocha push && ● Single failure stops process mocha cmsformatupdate && mocha crfaddition && mocha rfladdition && mocha contentupdate && mocha manifestupdate
  • 24. Automated Deployment: Overview Git S3 2) Jenkins polls for repo changes 1) Code is pushed to master 3) Code is zipped and uploaded to S3 Jenkins 4) Get a list of live servers in this group AWS API 5) SSH into each server and run the bootstrap script
  • 25. Automated Deployment: Bootstrap 5) SSH into each server and run the bootstrap script #!/bin/bash ZIP_LOCATION="s3://aviary/projectX/deployment.zip"; cd ~/projectX; sudo apt-get -y -q install nodejs@0.10.0; sudo apt-get -y -q install s3cmd; sudo npm install -g forever@0.10.8; Goals of the bootstrap.sh: 1. Ensure all dependencies are installed 2. Download and extract project 3. Ensure HTTP traffic is routed to the proper port 4. Keep the old version of the project live until the moment the new one is ready to go live # Missing step: create s3 configuration file s3cmd -c /usr/local/s3cfg.config get "$ZIP_LOCATION" theCds.zip; unzip -q -o deployment.zip iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-ports 8142; forever stopall; forever start server.js;
  • 27. Lessons Learned (1) ● Integration tests! ● Watch out for node and npm updates ○ Hardcode the node version you’re using ○ If you’re using package.json, version everything ● Node.js + MongoDb are a great couple ● Make sure you understand hoisting
  • 28. Lessons Learned (2) ● Always callback in async functions ● Always return after a callback ● Node doesn’t always run the same on all platforms ● Use middleware only when necessary ● Always store dates as Unix Timestamps ○ Timezones are a pain in your future ● Throwing unhandled errors will crash your process
  • 29. Conclusion Today, our production node servers: ● serve dynamic content to 20MM people (soon 70MM) ● power our website: aviary.com ● log real-time receipt data for every in-app purchase ● allow us to analyze hundreds of millions of events daily ● power quick scripts and one-off internal tools
  • 30. Questions? Comments also welcome nir@aviary.com - jack@aviary.com - ari@aviary.com - jeff@aviary.com …and by the way, WE’RE HIRING!