node js at paypal
DESCRIPTION
A case study in how PayPal revitalized its tech stack by moving from Java, JSP and proprietary solutions to node.js and dust.js templating. Developer agility was our primary motivation, but along the way we had to tackle enterprise culture and teach people that JavaScript is no longer a "toy", but a powerful tool to wield.TRANSCRIPT
In the Enterprise
By Jeff Harrell
Lenny Markus@LennyMarkus
Teams stopped waterfall process
Started agile with Lean UXQuick iterations; experience
design earlyWhite Board
CodeUsers
PayPal: Circa 2012
Using CSS, JavaScript and Templates
(in the wrong way…)
(Written in Java…)
Embracing the right technologies
Replaced JSP with dust.js templating
Node.js for mock applications
{ }Speeding up the process
Speeding up the process…
Idea Prototype in hours
This combo was fast!
“Node.js is not enterprise”
It’s a toy languageNot scalableInsecureSlowBlahBlahBlahBlah
Project Kraken
Bringing Node.Js into PayPalFocused on Web/Mobile
ApplicationsEmphasize developer velocityReplace our Java UI technology
stack
If you're having trouble getting sign-off on new technology, then try to pilot it vs. the old.
Pilot projects are harmless
• Identify Project• Begin integrating Node with
infrastructure
January
• Initial infrastructure offering ready
• Started developmenton pilot
March
• Node Pilot surpassed Java• Java put on holdJune
The pilot timeline
Pilot Results – Lines of Code
Node Java
7,40318,68
3
Pilot Results – Files
Node Java
84 255
/**If you’re reading this, that means you have been put in charge of my previous project.I am so, so sorry for you. God speed. */
// Houston, // we have a problem
// TODO: make this work// Magic. Do not touch.
//Catching exceptions // is for communists
/* ALL YOUR BASE ARE BELONG TO US */
Pilot Results – Comments
Node Java
62610,31
0
Pilot Results – Developers
Node Java
2 12
We proved it works!
Node Java
Node frameworks at scale
Needed to support thousands of devs
Node frameworks at scale
30+ Countries
Kraken.js
SecureExpress.jsTurnip
Babel.js
Internationalization
Application Framework
Application SecurityNPM Proxy
Kraken.js – A node.JS web application framework
Kraken.js
express + + +
PayPal’s Home-grown Node.JS framework
Supports for globalizationOut-of-the-box securityRobust configurationScalable
{ "port":80, "express":{
"views":"path:./myViews" }}
{ "port":8080, "express":{
"views":"path:./experimentation" }}
NODE_ENV=production
Configuration over manual wiring
Kraken.js
Clean, maintainable layout.
index
Template
Controller
Content
Kraken.js
Clear entry point for users
var app = { requestStart: function (server) {//...}, requestBeforeRoute: function (server) {//...}, requestAfterRoute: function (server) {//...}};
webcore .create(app) .listen();
Kraken.js
Kraken.js
Easily composite multiple applications
var app = { requestStart: function (server) {//...}, requestBeforeRoute: function (server) {//...}, requestAfterRoute: function (server) {//...}};
var otherApp = { //...}
webcore .create(app) //Maps to root .use('/fooApp', otherApp) .listen();
SecureExpress.js
• Enables Platform for Privacy Preferences Project (P3P) headers.
• Enables X-FRAME-OPTIONS headers to help prevent Clickjacking.
• Enables Content Security Policy (CSP) headers.
• Enables Cross Site Request Forgery (CSRF) headers.
Enables out-of-the-box security according to industry (and PayPal's ) best practices. This is done as middleware, so that all your requests/responses are automatically secured.
Babel.js – Internationalization (i18n)
• Load content bundles from a specific location
• Can localize templates on-the-fly
• Content stored in properties files
An extension for dust.js templates that enables localization / internationalization data to be loaded, and decorated on top of a template.
Babel.js – Internationalization (i18n)
index.title=PayPal for Merchants index.callToAction=Enroll now! index.greeting=Welcome {user}
# A list index.ccList[0]=Visa index.ccList[1]=Mastercard index.ccList[2]=Discover
# A map index.states[AL]=Alabama index.states[AK]=Alaska index.states[AZ]=Arizonaindex.states[CA]=California
index.title=PayPal pour commerçantsindex.callToAction= Inscrivez-vous! index.greeting=Bonjour {user}
# A list index.ccList[0]=Visa index.ccList[1]=CIBC
# A map index.states[ON]=Ontarioindex.states[AB]=Alberta index.states[MB]=Manitobaindex.states[QC]=Quebec
locales/US/en/index.properties locales/CA/fr/index.properties
Turnip – Your very own NPM
Turnip – Your very own NPM
• Support for module blacklists
• License compatibility checks
• Removes the need for replicating the public NPM
How do you enable private, company-wide deployment of node modules? Use a private NPM server in combination with Turnip, an NPM proxy.
Turnip – Your very own NPM
NPMJS.org
npm.intranet.compan
y.com
{"dependencies": {
"express": "~3.4.0",“privateMod”: “1.0.0”}
}
Best Practices
Custom Infrastructure
We all have some.
Always aim to use standard conventions in your Node.js code.
Custom Infrastructure
Sessions
Logging
client.addEvent('info', 'Hi')x = client.createTransaction()x.complete()
client.set('foo', 'bar')client.get('foo')client.update('foo', 'baz')client.destroy('foo')
Sessions
Logging
req.log('info', 'Hi!')req.time('Kraken')req.timeEnd('Kraken')
req.session.foo = 'bar'req.session.fooreq.session.foo = 'baz'delete req.session
Culture Clash – OSS vs. Closed
Stop "not written here" syndromeVersions often times aren't >= 1.0Collect knowledge from
communityGithub exposes sacred code
Hiccups found along the way…
Shared Server understanding
SSL Resumption
Scaling and Monitoring
var mySecretValue;
app.get('/route', function (req, res) { mySecretValue = req.params.secret; }
app.post('/route', function (req, res){ saveData(mySecretValue); }
• nginx can terminate SSL into your app.• To make https calls you'll want this for performance
• Use Node.js' cluster, Cluster2, or pm2 for management• Scale one process per core • Or per VM with 1-2 cores
Where are we today?
12 Node.js applications in the works
Checkout, activity and home pages
Clean boundaries between UI, app logic, and services
Open Source Software
Project Kraken. Releasing soon…