Tim Messerschmidt
@SeraAndroid
LondonJS Conf 2014
A story of!
technical debt
Application stacks at PayPal

C++

Java
Environments & Lean UX

Prototyping

Production
Application stacks at PayPal

C++
XSL

Java
JSP
Node
JS
Node & JS at PayPal
Moving away from Java architecture
•  CSS, HTML and even JS in Java
•  Originally replaced by JSP

Rapid development & deployment cycles
• 
• 
• 
• 

Open Source Stack
Bootstrap for frontend
JavaScript templating via Dust
V8 in PayPal’s C++ stack for legacy app UI
New stack at PayPal

Dust
C++

Java
 Node
Advantages of Node
Results of using Node at PayPal
•  Teams between 1/3 to 1/10 of Java teams
•  Doubled requests per second
•  35% decrease in average response time
•  Lines of code shrunk by factor 3 to 5
•  Development twice as fast
•  JS both on frontend and backend
Release the!
Kraken!
What is Kraken?
A JS suite on top of Node.js and Express
Preconfigured with different best practices
and tools:


• 
• 
• 
• 
• 

Dust for templates
LESS as CSS preprocessor
RequireJS as JS file and module loader
Grunt for running tasks
Runtime updates for UI code
But why?!
Project structure
Opinionated about separation of logic and
presentation


• 
• 
• 
• 
• 
• 

/config
/controllers
/models
/public/templates
/locales
/tests
Makara

Lusca

Adaro

Kappa
… and many more
Makara
Local content bundles
Internationalization support for Node apps

var i18n = require('makara');	
var provider = i18n.create(config);	
provider.getBundle('index', 'en_US', function (err, bundle) {	
var string = bundle.get('key');	
});
Property files for Makara
index.title=KrakenJS at LondonJS Conf	
index.speaker=Tim Messerschmidt	
index.greeting=Ahoi {attendeeName}!	
	
# A list	
index.speakers[0]=Lea Verou	
index.speakers[1]=Peter-Paul Koch	
Index.speakers[2]=Hannah Wolfe	
	
# A map	
index.sponsors[PP]=PayPal	
index.sponsors[GH]=GitHub	
	
# And subkeys	
index.conference.language=JS
Makara in use
Defining multiple values
/locales/US/en/index.properties	
•  index.greeting=Hello {name}!	

/locales/ES/es/index.properties	
•  index.greeting=Hola {name}!	
	

Accessing keys in templates
<h1>{@pre type="content" key="index.greeting"/}</h1>
Lusca
Security settings against various vulnerabilities


Cross-site request forgery support
Clickjacking / X-Frame-Options
Output escaping against XSS via Dust
Content Security Policy
Lusca configuration
Configuration in middleware.json	


"appsec": {	
	"csrf": true,	
	"csp": false,	
	"p3p": false,	
	"xframe": "SAMEORIGIN”	
}	
	

… or using Lusca’s methods
Lusca against CSRF
A token is added to the session automatically


var express = require('express'),	
	appsec = require('lusca'),
		
	server = express();	
	
server.use(appsec.csrf());	



The template needs to return the token:


<input type="hidden" name="_csrf" value="{_csrf}”>
Adaro
Brings Dust as default templating engine
Designed to work together with Makara


dustjs.onLoad = function (name, context, callback) {	
	// Custom file read/processing pipline	
	callback(err, str);	
}	
	
app.engine('dust', dustjs.dust({ cache: false }));	
app.set('view engine', 'dust');
Templating with Dust
Layout
	

<html>	
<body>	
{>"{_main}"/}	
</body>	
</html>	
	

Content page as partial


<div>Hello!</div>	
	
dust.render(’partial', { layout: ’template' }, ...);
Templating with Dust
Sections


{#modules}	
{name}, {description}{~n}	
{/modules}	
	

View context	


{ 	
	modules: [	
	
	{ name: “Makara”, description: “i18n” },	
	
	{ name: “Lusca”, description: “security settings” }	
	]	
}
Templating with Dust
Conditionals


{#modules}	
	{name}, {description}{~n}	
{:else}	
	No modules supported :(	
{/modules}	
	
{?modules}	
	modules exists!	
{/modules}	
	
{^modules}	
	No modules!	
{/modules}
Kappa
Serves as NPM Proxy
Enables support for private npm repos
Based on npm-delegate
hapi support
Global or local installation


npm install -g kappa	
kappa -c config.json
Configuring Kraken
Lives in /config/app.json	


Development vs. Production environments
•  2nd configuration allowed:
–  app-development.json	

•  Usage of NODE_ENV for environment
nconf for credentials and other variables
The Generator
Getting started
sudo npm install -g generator-kraken	
	
yo kraken	
	
,'""`.	
/ _ _ 	
|(@)(@)|
Release the Kraken!	
) __ (	
/,'))((`.	
(( (( )) ))	
` `)(' /'
Generation
yo kraken:controller myController	
	
Respond to XHR requests? (Y/n)	
	
create controllers/myController.js	
create test/myController.js
Result without XHR
var myModel = require('../models/model');	
	
module.exports = function (app) {	
	var model = new myModel();	
	
	app.get(’/ahoi', function (req, res) {
	 	res.render(’ahoi', model);	
	});	
};
Result with XHR
app.get('/ahoiXHR', function (req, res) {	
	res.format({	
	 	json: function () {	
	 	 	res.json(model);	
	 	},	
	 	html: function () {	
	 	 	res.render(’ahoiXHR', model);	
	 	}	
	});	
});
Models
yo kraken:model unicorn	
	
create models/unicorn.js	
	
module.exports = function UnicornModel() {	
	return {	
	 	name: ‘Charlie’	
	};	
};
Summary
Thanks!


Tim Messerschmidt
@SeraAndroid
tmesserschmidt@paypal.com
slideshare.com/paypal

KrakenJS

  • 1.
  • 2.
  • 3.
    Application stacks atPayPal C++ Java
  • 4.
    Environments & LeanUX Prototyping Production
  • 5.
    Application stacks atPayPal C++ XSL Java JSP Node JS
  • 6.
    Node & JSat PayPal Moving away from Java architecture •  CSS, HTML and even JS in Java •  Originally replaced by JSP Rapid development & deployment cycles •  •  •  •  Open Source Stack Bootstrap for frontend JavaScript templating via Dust V8 in PayPal’s C++ stack for legacy app UI
  • 7.
    New stack atPayPal Dust C++ Java Node
  • 8.
    Advantages of Node Resultsof using Node at PayPal •  Teams between 1/3 to 1/10 of Java teams •  Doubled requests per second •  35% decrease in average response time •  Lines of code shrunk by factor 3 to 5 •  Development twice as fast •  JS both on frontend and backend
  • 9.
  • 10.
    What is Kraken? AJS suite on top of Node.js and Express Preconfigured with different best practices and tools: •  •  •  •  •  Dust for templates LESS as CSS preprocessor RequireJS as JS file and module loader Grunt for running tasks Runtime updates for UI code
  • 11.
  • 12.
    Project structure Opinionated aboutseparation of logic and presentation •  •  •  •  •  •  /config /controllers /models /public/templates /locales /tests
  • 13.
  • 14.
  • 15.
    Makara Local content bundles Internationalizationsupport for Node apps var i18n = require('makara'); var provider = i18n.create(config); provider.getBundle('index', 'en_US', function (err, bundle) { var string = bundle.get('key'); });
  • 16.
    Property files forMakara index.title=KrakenJS at LondonJS Conf index.speaker=Tim Messerschmidt index.greeting=Ahoi {attendeeName}! # A list index.speakers[0]=Lea Verou index.speakers[1]=Peter-Paul Koch Index.speakers[2]=Hannah Wolfe # A map index.sponsors[PP]=PayPal index.sponsors[GH]=GitHub # And subkeys index.conference.language=JS
  • 17.
    Makara in use Definingmultiple values /locales/US/en/index.properties •  index.greeting=Hello {name}! /locales/ES/es/index.properties •  index.greeting=Hola {name}! Accessing keys in templates <h1>{@pre type="content" key="index.greeting"/}</h1>
  • 18.
    Lusca Security settings againstvarious vulnerabilities Cross-site request forgery support Clickjacking / X-Frame-Options Output escaping against XSS via Dust Content Security Policy
  • 19.
    Lusca configuration Configuration inmiddleware.json "appsec": { "csrf": true, "csp": false, "p3p": false, "xframe": "SAMEORIGIN” } … or using Lusca’s methods
  • 20.
    Lusca against CSRF Atoken is added to the session automatically var express = require('express'), appsec = require('lusca'), server = express(); server.use(appsec.csrf()); The template needs to return the token: <input type="hidden" name="_csrf" value="{_csrf}”>
  • 21.
    Adaro Brings Dust asdefault templating engine Designed to work together with Makara dustjs.onLoad = function (name, context, callback) { // Custom file read/processing pipline callback(err, str); } app.engine('dust', dustjs.dust({ cache: false })); app.set('view engine', 'dust');
  • 22.
    Templating with Dust Layout <html> <body> {>"{_main}"/} </body> </html> Contentpage as partial <div>Hello!</div> dust.render(’partial', { layout: ’template' }, ...);
  • 23.
    Templating with Dust Sections {#modules} {name},{description}{~n} {/modules} View context { modules: [ { name: “Makara”, description: “i18n” }, { name: “Lusca”, description: “security settings” } ] }
  • 24.
    Templating with Dust Conditionals {#modules} {name},{description}{~n} {:else} No modules supported :( {/modules} {?modules} modules exists! {/modules} {^modules} No modules! {/modules}
  • 25.
    Kappa Serves as NPMProxy Enables support for private npm repos Based on npm-delegate hapi support Global or local installation npm install -g kappa kappa -c config.json
  • 26.
    Configuring Kraken Lives in/config/app.json Development vs. Production environments •  2nd configuration allowed: –  app-development.json •  Usage of NODE_ENV for environment nconf for credentials and other variables
  • 27.
  • 28.
    Getting started sudo npminstall -g generator-kraken yo kraken ,'""`. / _ _ |(@)(@)| Release the Kraken! ) __ ( /,'))((`. (( (( )) )) ` `)(' /'
  • 29.
    Generation yo kraken:controller myController Respondto XHR requests? (Y/n) create controllers/myController.js create test/myController.js
  • 30.
    Result without XHR varmyModel = require('../models/model'); module.exports = function (app) { var model = new myModel(); app.get(’/ahoi', function (req, res) { res.render(’ahoi', model); }); };
  • 31.
    Result with XHR app.get('/ahoiXHR',function (req, res) { res.format({ json: function () { res.json(model); }, html: function () { res.render(’ahoiXHR', model); } }); });
  • 32.
    Models yo kraken:model unicorn createmodels/unicorn.js module.exports = function UnicornModel() { return { name: ‘Charlie’ }; };
  • 33.
  • 34.