SlideShare a Scribd company logo
1 of 75
Download to read offline
NodeJS: the good parts?
A skeptic’s view
Chris Richardson
Author of POJOs in Action
Founder of the original CloudFoundry.com
@crichardson chris@chrisrichardson.net http://plainoldobjects.com

@crichardson
Presentation goal

How a grumpy, gray-haired
server-side Java developer
discovered an appreciation
for NodeJS and JavaScript
@crichardson
! WARNING
VIEWER DISCRETION
IS ADVISED
@crichardson
About Chris
LispWorks
1980 1981 1982 1983 1984 1985 1986 1987 1988 1989

Z80
RPG 3 BCPL
Pascal
6502
C
Assembler
Basic
@crichardson
EJB
1990 1991 1992 1993 1994 1995 1996 1997 1998 1999

C++

@crichardson
CloudFoundry.com

2000 2001 2002 2003 2004 2005 2006 2007 2008 2009

@crichardson
About Chris

?
2010 2011 2012 2013 2014 2015 2016 2017 2018 2019

@crichardson
Agenda
Overview of NodeJS
JavaScript: Warts and all
The Reactor pattern: an event-driven architecture
NodeJS: There is a module for that
Building a front-end server with NodeJS

@crichardson
What’s NodeJS?

Designed for DIRTy apps
@crichardson
Growing rapidly

Busy!
@crichardson
NodeJS Hello World
app.js

Load a module
request handler

$ node app.js
$ curl http://localhost:1337

http://nodejs.org/

No complex configuration: simple! @crichardson
JavaScript
NodeJS

Modules

Reactor
pattern
@crichardson
JavaScript
NodeJS

Modules

Reactor
pattern
@crichardson
Dynamic and weakly-typed
Dynamic:
Types are associated with values - not variables
Define new program elements at runtime
Weakly typed:
Leave out arguments to methods
Read non-existent object properties
Add new properties by simply setting them
@crichardson
JavaScript is object-oriented
> var fred = {name: “Fred”, gender: “Male”};
undefined
> fred.name
“Fred”
> console.log("reading age=" + fred.age);
reading age=undefined
undefined
> fred.age = 99;
99
> fred
{ name: 'Fred',
gender: 'Male',
age: 99 }
> delete fred.age
true
> fred
{ name: 'Fred', gender: 'Male' }

Unordered key-value pairs
Keys = properties
Add property

Delete property

@crichardson
JavaScript is a prototypal
language

Person

__proto__
sayHello
...

Prototype

function
...
inherited

Chris __proto__
name
nickname

“Chris”
“CER”

overrides
object specific

@crichardson
Prototypal code

Not defined
here

$ node
> var person = { sayHello: function () { console.log("Hello " + this.name); }};
[Function]
> var chris = Object.create(person, {name: {value: "Chris"}});
undefined
> var sarah = Object.create(person, {name: {value: "Sarah"}});
undefined
> chris.sayHello();
Hello Chris
create using
undefined
properties
> sarah.sayHello();
prototype
Hello Sarah
undefined
> chris.sayHello = function () { console.log("Hello mate: " + this.name); };
[Function]
> chris.sayHello();
Hello mate: Chris
undefined
@crichardson
JavaScript is Functional
function makeGenerator(nextFunction) {

Return a function
closure

var value = 0;
return function() {
var current = value;
value = nextFunction(value);
return current;
};

Pass function as an
argument

}
var inc = makeGenerator(function (x) {return x + 1; });
> inc()
0
> inc()
1

@crichardson
But JavaScript was created
in a hurry
The ‘Java...’ name creates expectations that it can’t satisfy
Fake classes: Hides prototypes BUT still seems weird
global namespace
scope of vars is confusing
Missing return statement = confusion
‘function’ is really verbose
‘this’ is dynamically scoped
Unexpected implicit conversions: 99 == “99”!
truthy and falsy values
52-bit ints
@crichardson
Dynamic + weakly-typed (+ event-driven)
code
+
misspelt property names
lots of time spent in the abyss
Essential: Use IDE integrated
with JSLint/JSHint + tests
Prototypal languages have
benefits BUT
Developers really like classes
JavaScript prototypes lack the powerful features from
the Self language
e.g. Multiple (and dynamic) inheritance
http://www.cs.ucsb.edu/~urs/oocsb/self/papers/papers.html
@crichardson
Verbose function syntax
> var numbers = [1,2,3,4,5]
> numbers.filter(function (n) { return n % 2 == 0; } ).map(function (n) { return n * n; })
[ 4, 16 ]
>

Versus
Prelude> let numbers = [1,2,3,4,5]
Prelude> map (n -> n * n) (filter (n -> mod n 2 == 0) numbers)
[4,16]

Or
scala> val numbers = 1..5
scala> numbers filter { _ % 2 == 0} map { n => n * n }
Vector(4, 16)

@crichardson
Verbose DSLs
describe('SomeEntity', function () {
beforeEach(function () { ... some initialization ... });

Jasmine

it('should do something', function () {
...
expect(someExpression).toBe(someValue);
});
});

Versus
class SomeScalaTest ...{

Scalatest

before { ... some initialization ... }
it should "do something" in {
...
someExpression should be(someValue)
}

@crichardson
JavaScript is the language
of the web

“You have to use the programming
language you have, not the one that you
might want”
@crichardson
It works but the result is
lost opportunities
and
impeded progress
@crichardson
But if you think that this isn’t
a problem then perhaps ....
“Stockholm syndrome ... is a psychological
phenomenon in which hostages ... have
positive feelings toward their captors,
sometimes to the point of defending them...”
http://en.wikipedia.org/wiki/Stockholm_syndrome

@crichardson
Martin Fowler once said:
"...I'm one of those who despairs that a
language with such deep flaws plays such an
important role in computation. Still the
consequence of this is that we must take
javascript seriously as a first-class language
and concentrate on how to limit the damage
its flaws cause. ...."
http://martinfowler.com/bliki/gotoAarhus2012.html
@crichardson
Use just the good parts

Douglas
Crockford
http://www.crockford.com/

@crichardson
Use a language that
compiles to JavaScript
TypeScript
Classes and interfaces (dynamic structural typing)
Typed parameters and fields
Dart
Class-based OO
Optional static typing
Bidirectional binding with DOM elements
Less backwards compatibility with JavaScript
Also has it’s own VM

@crichardson
CoffeeScript Hello World
Classes :-)

http = require('http')

Concise

class HttpRequestHandler
constructor: (@message) ->

Bound method

handle: (req, res) =>
res.writeHead(200, {'Content-Type': 'text/plain'})
res.end(@message + 'n')

handler = new HttpRequestHandler "Hi There from CoffeeScript"
server = http.createServer(handler.handle)
server.listen(1338, '127.0.0.1')
console.log('Server running at http://127.0.0.1:1338/')
@crichardson
No escaping JavaScript
@crichardson
JavaScript
NodeJS

Modules

Reactor
pattern
@crichardson
About the Reactor pattern
Defined by Doug Schmidt in 1995
Pattern for writing scalable servers
Alternative to thread-per-connection model
Single threaded event loop dispatches events on
handles (e.g. sockets, file descriptors) to event handlers

@crichardson
Reactor pattern structure
Application
register_handler(h1)
register_handler(h2)
handle_events()

Initiation Dispatcher
handle_events()
handlers
register_handler(h)
uses

select(handlers)
for each h in handlers
h.handle_event(type)
end loop

Event Handler
handle_event(type)
get_handle()
owns

Synchronous Event
Demultiplexer
select()

notifies

handle
@crichardson
Benefits
Separation of concerns - event handlers separated
from low-level mechanism
More efficient - no thread context switching
Simplified concurrency - single threaded = no
possibility of concurrent access to shared state

@crichardson
Drawbacks
Non-pre-emptive - handlers must not take a long time
Difficult to understand and debug:
Inverted flow of control
Can’t single step through code easily
Limited stack traces
No stack-based context, e.g. thread locals, exception handlers
How to enforce try {} finally {} behavior?

@crichardson
NodeJS app = layers of event
handlers
Recurring
events
from
Event
Emitters

Application code
Event
listener

HTTP

Callback
function

DB driver

...

One time
events:
async
operation
completion

Basic networking/file-system/etc.
NodeJS event loop
@crichardson
Async code = callback hell
Scenarios:
Sequential: A

B

C

Scatter/Gather: A and B

C

Code quickly becomes very messy

@crichardson
Messy callback code
The result of
getProductDetails
getProductDetails = (productId, callback) ->
productId = req.params.productId
result = {productId: productId}

Propagate error

makeCallbackFor = (key) ->
(error, x) ->
if error
callback(error)
else
result[key] = x
if (result.productInfo and result.recommendations and result.reviews)
callback(undefined, result)

Update result

Gather

getProductInfo(productId, makeCallbackFor('productInfo'))
getRecommendations(productId, makeCallbackFor('recommendations'))
getReviews(makeCallbackFor('reviews'))

Scatter

@crichardson
Simplifying code with
Promises (a.k.a. Futures)
Functions return a promise - no callback parameter
A promise represents an eventual outcome
Use a library of functions for transforming and
composing promises
Promises/A+ specification - http://promises-aplus.github.io/promises-spec
when.js (part of cujo.js by SpringSource) is a popular
implementation

Crockford’s RQ library is another option
@crichardson
Simpler promise-based code
class ProductDetailsService
getProductDetails: (productId) ->
makeProductDetails =
(productInfo, recommendations, reviews) ->
productId: productId
productDetails: productInfo.entity
recommendations: recommendations.entity
reviews: reviews.entity
responses = [getProductInfo(productId),
getRecommendations(productId),
getReviews(productId)]
getReviews(productId)]
all(responses).spread(makeProductDetails)
all(responses) spread(makeProductDetails)
@crichardson
Not bad but lacks Scala’s
syntactic sugar
class ProductDetailsService .... {
def getProductDetails(productId: Long) = {
for (((productInfo, recommendations), reviews) <getProductInfo(productId) zip
getProductInfo(productId) zip
getRecommendations(productId) zip
getRecommendations(productId) zip
getReviews(productId)
getReviews(productId))
yield
ProductDetails(productInfo, recommendations, reviews)
}
}
@crichardson
Long running computations
Long running computation

blocks event loop for

other requests
Need to run outside of main event loop
Options:
Community: web workers threads
Built-in: NodeJS child processes

@crichardson
Using child processes
parent.js
var child = require('child_process').fork('child.js');
function sayHelloToChild() {
child.send({hello: "child"});
}

Create child process

Send message to child

setTimeout(sayHelloToChild, 1000);
child.on('message', function(m) {
console.log('parent received:', m);
});
function kill() {
child.kill();
}
setTimeout(kill, 2000);

child.js
process.on('message', function (m) {
console.log("child received message=", m);
process.send({ihateyou: "you ruined my life"})
});

@crichardson
Modern multi-core machines
vs. single-threaded runtime
Many components of many applications
Don’t need the scalability of the Reactor pattern
Request-level thread-based parallelism works fine
There are other concurrency options
Actors, Software transactional memory, ...
Go goroutines, Erlang processes, ...
Imposing a single-threaded complexity tax on the
entire application is questionable

@crichardson
JavaScript
NodeJS

Modules

Reactor
pattern
@crichardson
Core built-in modules
Basic networking
HTTP(S)
Filesystem
Events
Timers
...
Thousands of community
developed modules

https://npmjs.org/

web frameworks, SQL/NoSQL
database drivers, messaging, utilities...
@crichardson
What’s a module?
foo.js
One or more JavaScript files

exports.sayHello = function () {
console.log(“Hello”);
}

Optional native code:
Compiled during installation
JavaScript != systems programming language
Package.json - metadata including dependencies

@crichardson
Easy to install
$ npm install package-name --save

@crichardson
Easy to use
Core module OR
Path to file OR
module in node_modules
Module’s exports

var http = require(“http”)
var server = http.createServer...

@crichardson
Developing with NodeJS
modules
Application code
Your modules
Community modules
Core modules
@crichardson
There is a module for that...
Modules + glue code
=
rapid/easy application development
AWESOME!...
@crichardson
... BUT
Variable quality
Multiple incomplete/competing modules, e.g. MySQL
drivers without connection pooling!
Often abandoned
No notion of a Maven-style local repository/cache =
repeated downloads
...

@crichardson
To summarize

Flawed and
misunderstood

JavaScript
Rich but
variable quality
NodeJS

Modules

Scalable yet
costly and
often
unnecessary

Reactor pattern

@crichardson
How will future history view
NodeJS?

C++

?

EJB

@crichardson
Agenda
Overview of NodeJS
JavaScript: Warts and all
The Reactor pattern: an event-driven architecture
NodeJS: There is a module for that
Building a front-end server with NodeJS

@crichardson
So why care about
NodeJS?
Easy to write scalable network services
Easy to push events to the browser
Easy to get (small) stuff done

It has a role to play in modern
application architecture
@crichardson
Evolving from a monolithic
architecture....
WAR

StoreFrontUI
Product Info
Service
Recommendation
Service
Review
Service
Order
Service

@crichardson
... to a micro-service architecture
product info application

Product Info
Service

recommendations application
Store front application

StoreFrontUI

Recommendation
Service

reviews application

Review
Service

orders application

Order
Service

@crichardson
Presentation layer evolution....
WAR
StoreFrontUI

HTML / HTTP

View

Controller

Browser

+
JavaScript

Model

@crichardson
...Presentation layer evolution
Browser

View

Web application

Static
content

Controller
JSON-REST
Model

HTML 5/JavaScript
IOS/Android clients

Events

RESTful
Endpoints
Event
publisher

@crichardson
Directly connecting the front-end to the backend
Chatty API
View

REST

Product Info
service

REST

Recommendation
Service

AMQP

Controller

Review
service

Model
Traditional web
application

View

Controller

Model
Browser/Native App

Web unfriendly
protocols

@crichardson
NodeJS as an API gateway
Single entry point

Browser

View

Controller

NodeJS
Model
HTML 5 - JavaScript

Product Info
service

REST

Recommendation
Service

AMQP

Review
service

REST
proxy

Native App

View

API
Gateway

REST

Controller

Model

Event
publishing

Optimized Client
specific APIs

Protocol
translation

@crichardson
Serving static content with
the Express web framework
var express = require('express')
, http = require('http')
, app = express()
, server = http.createServer(app)
;

From public
sub directory

app.configure(function(){
...
app.use(express.static(__dirname + '/public'));
});
server.listen(8081);
@crichardson
RESTful web services

@crichardson
Proxying to backend server
express = require('express')
request = require('request')

Returns a request handler
that proxies to baseUrl

app = express.createServer()
proxyToBackend = (baseUrl) ->
(req, res) ->
callback = (error, response, body) -> console.log("error=", error)
originRequest = request(baseUrl + req.url, callback)
req.pipe(originRequest)
originRequest.pipe(res)
app.get('/productinfo/*', proxyToBackend('http://productinfo....'))
app.get('/recommendations/*', proxyToBackend(''http://recommendations...'))
app.get('/reviews/*', proxyToBackend('http://reviews...'))
@crichardson
Implementing coarsegrained mobile API
var express = require('express'),
...;
app.get('/productdetails/:productId', function (req, res) {
getProductDetails(req.params. productId).then(
function (productDetails) {
res.json(productDetails);
}
});

@crichardson
Delivering events to the
browser

@crichardson
Socket.io server-side
var express = require('express')
, http = require('http')
, amqp = require(‘amqp’)
....;

server.listen(8081);
...
var amqpCon = amqp.createConnection(...);

Handle
socket.io
connection

io.sockets.on('connection', function (socket) {
function amqpMessageHandler(message, headers, deliveryInfo) {
Republish
var m = JSON.parse(message.data.toString());
socket.emit(‘tick’, m);
as socket.io
};
event
amqpCon.queue(“”, {},
function(queue) {
queue.bind(“myExchange”, “”);
queue.subscribe(amqpMessageHandler);
Subscribe to
});
});
AMQP queue

https://github.com/cer/nodejs-clock

@crichardson
Socket.io - client side
<html>
<body>
The event is <span data-bind="text: ticker"></span>
<script src="/socket.io/socket.io.js"></script>
<script src="/knockout-2.0.0.js"></script>
<script src="/clock.js"></script>
</body>
</html>

Bind to model

Connect to
socket.io

clock.js
var socket = io.connect(location.hostname);
function ClockModel() {
self.ticker = ko.observable(1);
socket.on('tick', function (data) {
self.ticker(data);
});
};
ko.applyBindings(new ClockModel());

Subscribe
to tick event
Update
model

@crichardson
NodeJS is also great for writing
backend micro-services
“Network elements”
Simply ‘route, filter and transform packets’
Have minimal business logic

@crichardson
NodeJS-powered home security
FTP Server
Log file

FTP Server
Upload directory

Upload2S3

S3

SQS Queue

UploadQueue
Processor

DynamoDB
@crichardson
Summary
JavaScript is a very flawed language
The asynchronous model is often unnecessary; very
constraining; and adds complexity

BUT despite those problems

Today, NodeJS is remarkably useful for building networkfocussed components
@crichardson
@crichardson

chris@chrisrichardson.net

Questions?

http://plainoldobjects.com

@crichardson

More Related Content

What's hot

Functional Programming with Immutable Data Structures
Functional Programming with Immutable Data StructuresFunctional Programming with Immutable Data Structures
Functional Programming with Immutable Data Structureselliando dias
 
Dan Persa, Maximilian Fellner - The recipe for scalable frontends - Codemotio...
Dan Persa, Maximilian Fellner - The recipe for scalable frontends - Codemotio...Dan Persa, Maximilian Fellner - The recipe for scalable frontends - Codemotio...
Dan Persa, Maximilian Fellner - The recipe for scalable frontends - Codemotio...Codemotion
 
Lightbend Lagom: Microservices Just Right (Scala Days 2016 Berlin)
Lightbend Lagom: Microservices Just Right (Scala Days 2016 Berlin)Lightbend Lagom: Microservices Just Right (Scala Days 2016 Berlin)
Lightbend Lagom: Microservices Just Right (Scala Days 2016 Berlin)mircodotta
 

What's hot (6)

Zen of Akka
Zen of AkkaZen of Akka
Zen of Akka
 
Object Oriented Javascript
Object Oriented JavascriptObject Oriented Javascript
Object Oriented Javascript
 
Node js internal
Node js internalNode js internal
Node js internal
 
Functional Programming with Immutable Data Structures
Functional Programming with Immutable Data StructuresFunctional Programming with Immutable Data Structures
Functional Programming with Immutable Data Structures
 
Dan Persa, Maximilian Fellner - The recipe for scalable frontends - Codemotio...
Dan Persa, Maximilian Fellner - The recipe for scalable frontends - Codemotio...Dan Persa, Maximilian Fellner - The recipe for scalable frontends - Codemotio...
Dan Persa, Maximilian Fellner - The recipe for scalable frontends - Codemotio...
 
Lightbend Lagom: Microservices Just Right (Scala Days 2016 Berlin)
Lightbend Lagom: Microservices Just Right (Scala Days 2016 Berlin)Lightbend Lagom: Microservices Just Right (Scala Days 2016 Berlin)
Lightbend Lagom: Microservices Just Right (Scala Days 2016 Berlin)
 

Similar to NodeJS: the good parts? A skeptic’s view (jmaghreb, jmaghreb2013)

NodeJS: the good parts? A skeptic’s view (devnexus2014)
NodeJS: the good parts? A skeptic’s view (devnexus2014)NodeJS: the good parts? A skeptic’s view (devnexus2014)
NodeJS: the good parts? A skeptic’s view (devnexus2014)Chris Richardson
 
Futures and Rx Observables: powerful abstractions for consuming web services ...
Futures and Rx Observables: powerful abstractions for consuming web services ...Futures and Rx Observables: powerful abstractions for consuming web services ...
Futures and Rx Observables: powerful abstractions for consuming web services ...Chris Richardson
 
Consuming web services asynchronously with Futures and Rx Observables (svcc, ...
Consuming web services asynchronously with Futures and Rx Observables (svcc, ...Consuming web services asynchronously with Futures and Rx Observables (svcc, ...
Consuming web services asynchronously with Futures and Rx Observables (svcc, ...Chris Richardson
 
NodeJS: the good parts? A skeptic’s view (jax jax2013)
NodeJS: the good parts? A skeptic’s view (jax jax2013)NodeJS: the good parts? A skeptic’s view (jax jax2013)
NodeJS: the good parts? A skeptic’s view (jax jax2013)Chris Richardson
 
Map, Flatmap and Reduce are Your New Best Friends: Simpler Collections, Concu...
Map, Flatmap and Reduce are Your New Best Friends: Simpler Collections, Concu...Map, Flatmap and Reduce are Your New Best Friends: Simpler Collections, Concu...
Map, Flatmap and Reduce are Your New Best Friends: Simpler Collections, Concu...Chris Richardson
 
HTML5 for the Silverlight Guy
HTML5 for the Silverlight GuyHTML5 for the Silverlight Guy
HTML5 for the Silverlight GuyDavid Padbury
 
The curious Life of JavaScript - Talk at SI-SE 2015
The curious Life of JavaScript - Talk at SI-SE 2015The curious Life of JavaScript - Talk at SI-SE 2015
The curious Life of JavaScript - Talk at SI-SE 2015jbandi
 
Microservices + Events + Docker = A Perfect Trio by Docker Captain Chris Rich...
Microservices + Events + Docker = A Perfect Trio by Docker Captain Chris Rich...Microservices + Events + Docker = A Perfect Trio by Docker Captain Chris Rich...
Microservices + Events + Docker = A Perfect Trio by Docker Captain Chris Rich...Docker, Inc.
 
Microservices + Events + Docker = A Perfect Trio (dockercon)
Microservices + Events + Docker = A Perfect Trio (dockercon)Microservices + Events + Docker = A Perfect Trio (dockercon)
Microservices + Events + Docker = A Perfect Trio (dockercon)Chris Richardson
 
Bringing your app to the web with Dart - Chris Buckett (Entity Group)
Bringing your app to the web with Dart - Chris Buckett (Entity Group)Bringing your app to the web with Dart - Chris Buckett (Entity Group)
Bringing your app to the web with Dart - Chris Buckett (Entity Group)jaxLondonConference
 
Map, flatmap and reduce are your new best friends (javaone, svcc)
Map, flatmap and reduce are your new best friends (javaone, svcc)Map, flatmap and reduce are your new best friends (javaone, svcc)
Map, flatmap and reduce are your new best friends (javaone, svcc)Chris Richardson
 
The Future of Web Attacks - CONFidence 2010
The Future of Web Attacks - CONFidence 2010The Future of Web Attacks - CONFidence 2010
The Future of Web Attacks - CONFidence 2010Mario Heiderich
 
Construction Techniques For Domain Specific Languages
Construction Techniques For Domain Specific LanguagesConstruction Techniques For Domain Specific Languages
Construction Techniques For Domain Specific LanguagesThoughtWorks
 
Alberto Maria Angelo Paro - Isomorphic programming in Scala and WebDevelopmen...
Alberto Maria Angelo Paro - Isomorphic programming in Scala and WebDevelopmen...Alberto Maria Angelo Paro - Isomorphic programming in Scala and WebDevelopmen...
Alberto Maria Angelo Paro - Isomorphic programming in Scala and WebDevelopmen...Codemotion
 
Building Microservices with Scala, functional domain models and Spring Boot -...
Building Microservices with Scala, functional domain models and Spring Boot -...Building Microservices with Scala, functional domain models and Spring Boot -...
Building Microservices with Scala, functional domain models and Spring Boot -...JAXLondon2014
 

Similar to NodeJS: the good parts? A skeptic’s view (jmaghreb, jmaghreb2013) (20)

NodeJS: the good parts? A skeptic’s view (devnexus2014)
NodeJS: the good parts? A skeptic’s view (devnexus2014)NodeJS: the good parts? A skeptic’s view (devnexus2014)
NodeJS: the good parts? A skeptic’s view (devnexus2014)
 
Futures and Rx Observables: powerful abstractions for consuming web services ...
Futures and Rx Observables: powerful abstractions for consuming web services ...Futures and Rx Observables: powerful abstractions for consuming web services ...
Futures and Rx Observables: powerful abstractions for consuming web services ...
 
Consuming web services asynchronously with Futures and Rx Observables (svcc, ...
Consuming web services asynchronously with Futures and Rx Observables (svcc, ...Consuming web services asynchronously with Futures and Rx Observables (svcc, ...
Consuming web services asynchronously with Futures and Rx Observables (svcc, ...
 
NodeJS: the good parts? A skeptic’s view (jax jax2013)
NodeJS: the good parts? A skeptic’s view (jax jax2013)NodeJS: the good parts? A skeptic’s view (jax jax2013)
NodeJS: the good parts? A skeptic’s view (jax jax2013)
 
Foolangjs
FoolangjsFoolangjs
Foolangjs
 
Map, Flatmap and Reduce are Your New Best Friends: Simpler Collections, Concu...
Map, Flatmap and Reduce are Your New Best Friends: Simpler Collections, Concu...Map, Flatmap and Reduce are Your New Best Friends: Simpler Collections, Concu...
Map, Flatmap and Reduce are Your New Best Friends: Simpler Collections, Concu...
 
All of Javascript
All of JavascriptAll of Javascript
All of Javascript
 
HTML5 for the Silverlight Guy
HTML5 for the Silverlight GuyHTML5 for the Silverlight Guy
HTML5 for the Silverlight Guy
 
The curious Life of JavaScript - Talk at SI-SE 2015
The curious Life of JavaScript - Talk at SI-SE 2015The curious Life of JavaScript - Talk at SI-SE 2015
The curious Life of JavaScript - Talk at SI-SE 2015
 
Microservices + Events + Docker = A Perfect Trio by Docker Captain Chris Rich...
Microservices + Events + Docker = A Perfect Trio by Docker Captain Chris Rich...Microservices + Events + Docker = A Perfect Trio by Docker Captain Chris Rich...
Microservices + Events + Docker = A Perfect Trio by Docker Captain Chris Rich...
 
Microservices + Events + Docker = A Perfect Trio (dockercon)
Microservices + Events + Docker = A Perfect Trio (dockercon)Microservices + Events + Docker = A Perfect Trio (dockercon)
Microservices + Events + Docker = A Perfect Trio (dockercon)
 
Bringing your app to the web with Dart - Chris Buckett (Entity Group)
Bringing your app to the web with Dart - Chris Buckett (Entity Group)Bringing your app to the web with Dart - Chris Buckett (Entity Group)
Bringing your app to the web with Dart - Chris Buckett (Entity Group)
 
Mlocjs buzdin
Mlocjs buzdinMlocjs buzdin
Mlocjs buzdin
 
Map, flatmap and reduce are your new best friends (javaone, svcc)
Map, flatmap and reduce are your new best friends (javaone, svcc)Map, flatmap and reduce are your new best friends (javaone, svcc)
Map, flatmap and reduce are your new best friends (javaone, svcc)
 
Robots in Swift
Robots in SwiftRobots in Swift
Robots in Swift
 
The Future of Web Attacks - CONFidence 2010
The Future of Web Attacks - CONFidence 2010The Future of Web Attacks - CONFidence 2010
The Future of Web Attacks - CONFidence 2010
 
All of javascript
All of javascriptAll of javascript
All of javascript
 
Construction Techniques For Domain Specific Languages
Construction Techniques For Domain Specific LanguagesConstruction Techniques For Domain Specific Languages
Construction Techniques For Domain Specific Languages
 
Alberto Maria Angelo Paro - Isomorphic programming in Scala and WebDevelopmen...
Alberto Maria Angelo Paro - Isomorphic programming in Scala and WebDevelopmen...Alberto Maria Angelo Paro - Isomorphic programming in Scala and WebDevelopmen...
Alberto Maria Angelo Paro - Isomorphic programming in Scala and WebDevelopmen...
 
Building Microservices with Scala, functional domain models and Spring Boot -...
Building Microservices with Scala, functional domain models and Spring Boot -...Building Microservices with Scala, functional domain models and Spring Boot -...
Building Microservices with Scala, functional domain models and Spring Boot -...
 

More from Chris Richardson

The microservice architecture: what, why, when and how?
The microservice architecture: what, why, when and how?The microservice architecture: what, why, when and how?
The microservice architecture: what, why, when and how?Chris Richardson
 
More the merrier: a microservices anti-pattern
More the merrier: a microservices anti-patternMore the merrier: a microservices anti-pattern
More the merrier: a microservices anti-patternChris Richardson
 
YOW London - Considering Migrating a Monolith to Microservices? A Dark Energy...
YOW London - Considering Migrating a Monolith to Microservices? A Dark Energy...YOW London - Considering Migrating a Monolith to Microservices? A Dark Energy...
YOW London - Considering Migrating a Monolith to Microservices? A Dark Energy...Chris Richardson
 
Dark Energy, Dark Matter and the Microservices Patterns?!
Dark Energy, Dark Matter and the Microservices Patterns?!Dark Energy, Dark Matter and the Microservices Patterns?!
Dark Energy, Dark Matter and the Microservices Patterns?!Chris Richardson
 
Dark energy, dark matter and microservice architecture collaboration patterns
Dark energy, dark matter and microservice architecture collaboration patternsDark energy, dark matter and microservice architecture collaboration patterns
Dark energy, dark matter and microservice architecture collaboration patternsChris Richardson
 
Scenarios_and_Architecture_SkillsMatter_April_2022.pdf
Scenarios_and_Architecture_SkillsMatter_April_2022.pdfScenarios_and_Architecture_SkillsMatter_April_2022.pdf
Scenarios_and_Architecture_SkillsMatter_April_2022.pdfChris Richardson
 
Using patterns and pattern languages to make better architectural decisions
Using patterns and pattern languages to make better architectural decisions Using patterns and pattern languages to make better architectural decisions
Using patterns and pattern languages to make better architectural decisions Chris Richardson
 
iSAQB gathering 2021 keynote - Architectural patterns for rapid, reliable, fr...
iSAQB gathering 2021 keynote - Architectural patterns for rapid, reliable, fr...iSAQB gathering 2021 keynote - Architectural patterns for rapid, reliable, fr...
iSAQB gathering 2021 keynote - Architectural patterns for rapid, reliable, fr...Chris Richardson
 
Events to the rescue: solving distributed data problems in a microservice arc...
Events to the rescue: solving distributed data problems in a microservice arc...Events to the rescue: solving distributed data problems in a microservice arc...
Events to the rescue: solving distributed data problems in a microservice arc...Chris Richardson
 
A pattern language for microservices - June 2021
A pattern language for microservices - June 2021 A pattern language for microservices - June 2021
A pattern language for microservices - June 2021 Chris Richardson
 
QConPlus 2021: Minimizing Design Time Coupling in a Microservice Architecture
QConPlus 2021: Minimizing Design Time Coupling in a Microservice ArchitectureQConPlus 2021: Minimizing Design Time Coupling in a Microservice Architecture
QConPlus 2021: Minimizing Design Time Coupling in a Microservice ArchitectureChris Richardson
 
Mucon 2021 - Dark energy, dark matter: imperfect metaphors for designing micr...
Mucon 2021 - Dark energy, dark matter: imperfect metaphors for designing micr...Mucon 2021 - Dark energy, dark matter: imperfect metaphors for designing micr...
Mucon 2021 - Dark energy, dark matter: imperfect metaphors for designing micr...Chris Richardson
 
Designing loosely coupled services
Designing loosely coupled servicesDesigning loosely coupled services
Designing loosely coupled servicesChris Richardson
 
Microservices - an architecture that enables DevOps (T Systems DevOps day)
Microservices - an architecture that enables DevOps (T Systems DevOps day)Microservices - an architecture that enables DevOps (T Systems DevOps day)
Microservices - an architecture that enables DevOps (T Systems DevOps day)Chris Richardson
 
DDD SoCal: Decompose your monolith: Ten principles for refactoring a monolith...
DDD SoCal: Decompose your monolith: Ten principles for refactoring a monolith...DDD SoCal: Decompose your monolith: Ten principles for refactoring a monolith...
DDD SoCal: Decompose your monolith: Ten principles for refactoring a monolith...Chris Richardson
 
Decompose your monolith: Six principles for refactoring a monolith to microse...
Decompose your monolith: Six principles for refactoring a monolith to microse...Decompose your monolith: Six principles for refactoring a monolith to microse...
Decompose your monolith: Six principles for refactoring a monolith to microse...Chris Richardson
 
TDC2020 - The microservice architecture: enabling rapid, reliable, frequent a...
TDC2020 - The microservice architecture: enabling rapid, reliable, frequent a...TDC2020 - The microservice architecture: enabling rapid, reliable, frequent a...
TDC2020 - The microservice architecture: enabling rapid, reliable, frequent a...Chris Richardson
 
Overview of the Eventuate Tram Customers and Orders application
Overview of the Eventuate Tram Customers and Orders applicationOverview of the Eventuate Tram Customers and Orders application
Overview of the Eventuate Tram Customers and Orders applicationChris Richardson
 
An overview of the Eventuate Platform
An overview of the Eventuate PlatformAn overview of the Eventuate Platform
An overview of the Eventuate PlatformChris Richardson
 
#DevNexus202 Decompose your monolith
#DevNexus202 Decompose your monolith#DevNexus202 Decompose your monolith
#DevNexus202 Decompose your monolithChris Richardson
 

More from Chris Richardson (20)

The microservice architecture: what, why, when and how?
The microservice architecture: what, why, when and how?The microservice architecture: what, why, when and how?
The microservice architecture: what, why, when and how?
 
More the merrier: a microservices anti-pattern
More the merrier: a microservices anti-patternMore the merrier: a microservices anti-pattern
More the merrier: a microservices anti-pattern
 
YOW London - Considering Migrating a Monolith to Microservices? A Dark Energy...
YOW London - Considering Migrating a Monolith to Microservices? A Dark Energy...YOW London - Considering Migrating a Monolith to Microservices? A Dark Energy...
YOW London - Considering Migrating a Monolith to Microservices? A Dark Energy...
 
Dark Energy, Dark Matter and the Microservices Patterns?!
Dark Energy, Dark Matter and the Microservices Patterns?!Dark Energy, Dark Matter and the Microservices Patterns?!
Dark Energy, Dark Matter and the Microservices Patterns?!
 
Dark energy, dark matter and microservice architecture collaboration patterns
Dark energy, dark matter and microservice architecture collaboration patternsDark energy, dark matter and microservice architecture collaboration patterns
Dark energy, dark matter and microservice architecture collaboration patterns
 
Scenarios_and_Architecture_SkillsMatter_April_2022.pdf
Scenarios_and_Architecture_SkillsMatter_April_2022.pdfScenarios_and_Architecture_SkillsMatter_April_2022.pdf
Scenarios_and_Architecture_SkillsMatter_April_2022.pdf
 
Using patterns and pattern languages to make better architectural decisions
Using patterns and pattern languages to make better architectural decisions Using patterns and pattern languages to make better architectural decisions
Using patterns and pattern languages to make better architectural decisions
 
iSAQB gathering 2021 keynote - Architectural patterns for rapid, reliable, fr...
iSAQB gathering 2021 keynote - Architectural patterns for rapid, reliable, fr...iSAQB gathering 2021 keynote - Architectural patterns for rapid, reliable, fr...
iSAQB gathering 2021 keynote - Architectural patterns for rapid, reliable, fr...
 
Events to the rescue: solving distributed data problems in a microservice arc...
Events to the rescue: solving distributed data problems in a microservice arc...Events to the rescue: solving distributed data problems in a microservice arc...
Events to the rescue: solving distributed data problems in a microservice arc...
 
A pattern language for microservices - June 2021
A pattern language for microservices - June 2021 A pattern language for microservices - June 2021
A pattern language for microservices - June 2021
 
QConPlus 2021: Minimizing Design Time Coupling in a Microservice Architecture
QConPlus 2021: Minimizing Design Time Coupling in a Microservice ArchitectureQConPlus 2021: Minimizing Design Time Coupling in a Microservice Architecture
QConPlus 2021: Minimizing Design Time Coupling in a Microservice Architecture
 
Mucon 2021 - Dark energy, dark matter: imperfect metaphors for designing micr...
Mucon 2021 - Dark energy, dark matter: imperfect metaphors for designing micr...Mucon 2021 - Dark energy, dark matter: imperfect metaphors for designing micr...
Mucon 2021 - Dark energy, dark matter: imperfect metaphors for designing micr...
 
Designing loosely coupled services
Designing loosely coupled servicesDesigning loosely coupled services
Designing loosely coupled services
 
Microservices - an architecture that enables DevOps (T Systems DevOps day)
Microservices - an architecture that enables DevOps (T Systems DevOps day)Microservices - an architecture that enables DevOps (T Systems DevOps day)
Microservices - an architecture that enables DevOps (T Systems DevOps day)
 
DDD SoCal: Decompose your monolith: Ten principles for refactoring a monolith...
DDD SoCal: Decompose your monolith: Ten principles for refactoring a monolith...DDD SoCal: Decompose your monolith: Ten principles for refactoring a monolith...
DDD SoCal: Decompose your monolith: Ten principles for refactoring a monolith...
 
Decompose your monolith: Six principles for refactoring a monolith to microse...
Decompose your monolith: Six principles for refactoring a monolith to microse...Decompose your monolith: Six principles for refactoring a monolith to microse...
Decompose your monolith: Six principles for refactoring a monolith to microse...
 
TDC2020 - The microservice architecture: enabling rapid, reliable, frequent a...
TDC2020 - The microservice architecture: enabling rapid, reliable, frequent a...TDC2020 - The microservice architecture: enabling rapid, reliable, frequent a...
TDC2020 - The microservice architecture: enabling rapid, reliable, frequent a...
 
Overview of the Eventuate Tram Customers and Orders application
Overview of the Eventuate Tram Customers and Orders applicationOverview of the Eventuate Tram Customers and Orders application
Overview of the Eventuate Tram Customers and Orders application
 
An overview of the Eventuate Platform
An overview of the Eventuate PlatformAn overview of the Eventuate Platform
An overview of the Eventuate Platform
 
#DevNexus202 Decompose your monolith
#DevNexus202 Decompose your monolith#DevNexus202 Decompose your monolith
#DevNexus202 Decompose your monolith
 

Recently uploaded

DSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningDSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningLars Bell
 
Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupFlorian Wilhelm
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebUiPathCommunity
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii SoldatenkoFwdays
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Mark Simos
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.Curtis Poe
 
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
 
"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
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024Lorenzo Miniero
 
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
 
Scanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsScanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsRizwan Syed
 
Story boards and shot lists for my a level piece
Story boards and shot lists for my a level pieceStory boards and shot lists for my a level piece
Story boards and shot lists for my a level piececharlottematthew16
 
Search Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfSearch Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfRankYa
 
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
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 3652toLead Limited
 
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
 
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
 
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
 

Recently uploaded (20)

DSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningDSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine Tuning
 
Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project Setup
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio Web
 
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptxE-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.
 
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
 
"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
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024
 
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
 
Scanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsScanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL Certs
 
Story boards and shot lists for my a level piece
Story boards and shot lists for my a level pieceStory boards and shot lists for my a level piece
Story boards and shot lists for my a level piece
 
Search Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfSearch Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdf
 
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
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365
 
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
 
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
 
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
 

NodeJS: the good parts? A skeptic’s view (jmaghreb, jmaghreb2013)

  • 1. NodeJS: the good parts? A skeptic’s view Chris Richardson Author of POJOs in Action Founder of the original CloudFoundry.com @crichardson chris@chrisrichardson.net http://plainoldobjects.com @crichardson
  • 2. Presentation goal How a grumpy, gray-haired server-side Java developer discovered an appreciation for NodeJS and JavaScript @crichardson
  • 3. ! WARNING VIEWER DISCRETION IS ADVISED @crichardson
  • 4. About Chris LispWorks 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 Z80 RPG 3 BCPL Pascal 6502 C Assembler Basic @crichardson
  • 5. EJB 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 C++ @crichardson
  • 6. CloudFoundry.com 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 @crichardson
  • 7. About Chris ? 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 @crichardson
  • 8. Agenda Overview of NodeJS JavaScript: Warts and all The Reactor pattern: an event-driven architecture NodeJS: There is a module for that Building a front-end server with NodeJS @crichardson
  • 9. What’s NodeJS? Designed for DIRTy apps @crichardson
  • 11. NodeJS Hello World app.js Load a module request handler $ node app.js $ curl http://localhost:1337 http://nodejs.org/ No complex configuration: simple! @crichardson
  • 14. Dynamic and weakly-typed Dynamic: Types are associated with values - not variables Define new program elements at runtime Weakly typed: Leave out arguments to methods Read non-existent object properties Add new properties by simply setting them @crichardson
  • 15. JavaScript is object-oriented > var fred = {name: “Fred”, gender: “Male”}; undefined > fred.name “Fred” > console.log("reading age=" + fred.age); reading age=undefined undefined > fred.age = 99; 99 > fred { name: 'Fred', gender: 'Male', age: 99 } > delete fred.age true > fred { name: 'Fred', gender: 'Male' } Unordered key-value pairs Keys = properties Add property Delete property @crichardson
  • 16. JavaScript is a prototypal language Person __proto__ sayHello ... Prototype function ... inherited Chris __proto__ name nickname “Chris” “CER” overrides object specific @crichardson
  • 17. Prototypal code Not defined here $ node > var person = { sayHello: function () { console.log("Hello " + this.name); }}; [Function] > var chris = Object.create(person, {name: {value: "Chris"}}); undefined > var sarah = Object.create(person, {name: {value: "Sarah"}}); undefined > chris.sayHello(); Hello Chris create using undefined properties > sarah.sayHello(); prototype Hello Sarah undefined > chris.sayHello = function () { console.log("Hello mate: " + this.name); }; [Function] > chris.sayHello(); Hello mate: Chris undefined @crichardson
  • 18. JavaScript is Functional function makeGenerator(nextFunction) { Return a function closure var value = 0; return function() { var current = value; value = nextFunction(value); return current; }; Pass function as an argument } var inc = makeGenerator(function (x) {return x + 1; }); > inc() 0 > inc() 1 @crichardson
  • 19. But JavaScript was created in a hurry The ‘Java...’ name creates expectations that it can’t satisfy Fake classes: Hides prototypes BUT still seems weird global namespace scope of vars is confusing Missing return statement = confusion ‘function’ is really verbose ‘this’ is dynamically scoped Unexpected implicit conversions: 99 == “99”! truthy and falsy values 52-bit ints @crichardson
  • 20. Dynamic + weakly-typed (+ event-driven) code + misspelt property names lots of time spent in the abyss Essential: Use IDE integrated with JSLint/JSHint + tests
  • 21. Prototypal languages have benefits BUT Developers really like classes JavaScript prototypes lack the powerful features from the Self language e.g. Multiple (and dynamic) inheritance http://www.cs.ucsb.edu/~urs/oocsb/self/papers/papers.html @crichardson
  • 22. Verbose function syntax > var numbers = [1,2,3,4,5] > numbers.filter(function (n) { return n % 2 == 0; } ).map(function (n) { return n * n; }) [ 4, 16 ] > Versus Prelude> let numbers = [1,2,3,4,5] Prelude> map (n -> n * n) (filter (n -> mod n 2 == 0) numbers) [4,16] Or scala> val numbers = 1..5 scala> numbers filter { _ % 2 == 0} map { n => n * n } Vector(4, 16) @crichardson
  • 23. Verbose DSLs describe('SomeEntity', function () { beforeEach(function () { ... some initialization ... }); Jasmine it('should do something', function () { ... expect(someExpression).toBe(someValue); }); }); Versus class SomeScalaTest ...{ Scalatest before { ... some initialization ... } it should "do something" in { ... someExpression should be(someValue) } @crichardson
  • 24. JavaScript is the language of the web “You have to use the programming language you have, not the one that you might want” @crichardson
  • 25. It works but the result is lost opportunities and impeded progress @crichardson
  • 26. But if you think that this isn’t a problem then perhaps .... “Stockholm syndrome ... is a psychological phenomenon in which hostages ... have positive feelings toward their captors, sometimes to the point of defending them...” http://en.wikipedia.org/wiki/Stockholm_syndrome @crichardson
  • 27. Martin Fowler once said: "...I'm one of those who despairs that a language with such deep flaws plays such an important role in computation. Still the consequence of this is that we must take javascript seriously as a first-class language and concentrate on how to limit the damage its flaws cause. ...." http://martinfowler.com/bliki/gotoAarhus2012.html @crichardson
  • 28. Use just the good parts Douglas Crockford http://www.crockford.com/ @crichardson
  • 29. Use a language that compiles to JavaScript TypeScript Classes and interfaces (dynamic structural typing) Typed parameters and fields Dart Class-based OO Optional static typing Bidirectional binding with DOM elements Less backwards compatibility with JavaScript Also has it’s own VM @crichardson
  • 30. CoffeeScript Hello World Classes :-) http = require('http') Concise class HttpRequestHandler constructor: (@message) -> Bound method handle: (req, res) => res.writeHead(200, {'Content-Type': 'text/plain'}) res.end(@message + 'n') handler = new HttpRequestHandler "Hi There from CoffeeScript" server = http.createServer(handler.handle) server.listen(1338, '127.0.0.1') console.log('Server running at http://127.0.0.1:1338/') @crichardson
  • 33. About the Reactor pattern Defined by Doug Schmidt in 1995 Pattern for writing scalable servers Alternative to thread-per-connection model Single threaded event loop dispatches events on handles (e.g. sockets, file descriptors) to event handlers @crichardson
  • 34. Reactor pattern structure Application register_handler(h1) register_handler(h2) handle_events() Initiation Dispatcher handle_events() handlers register_handler(h) uses select(handlers) for each h in handlers h.handle_event(type) end loop Event Handler handle_event(type) get_handle() owns Synchronous Event Demultiplexer select() notifies handle @crichardson
  • 35. Benefits Separation of concerns - event handlers separated from low-level mechanism More efficient - no thread context switching Simplified concurrency - single threaded = no possibility of concurrent access to shared state @crichardson
  • 36. Drawbacks Non-pre-emptive - handlers must not take a long time Difficult to understand and debug: Inverted flow of control Can’t single step through code easily Limited stack traces No stack-based context, e.g. thread locals, exception handlers How to enforce try {} finally {} behavior? @crichardson
  • 37. NodeJS app = layers of event handlers Recurring events from Event Emitters Application code Event listener HTTP Callback function DB driver ... One time events: async operation completion Basic networking/file-system/etc. NodeJS event loop @crichardson
  • 38. Async code = callback hell Scenarios: Sequential: A B C Scatter/Gather: A and B C Code quickly becomes very messy @crichardson
  • 39. Messy callback code The result of getProductDetails getProductDetails = (productId, callback) -> productId = req.params.productId result = {productId: productId} Propagate error makeCallbackFor = (key) -> (error, x) -> if error callback(error) else result[key] = x if (result.productInfo and result.recommendations and result.reviews) callback(undefined, result) Update result Gather getProductInfo(productId, makeCallbackFor('productInfo')) getRecommendations(productId, makeCallbackFor('recommendations')) getReviews(makeCallbackFor('reviews')) Scatter @crichardson
  • 40. Simplifying code with Promises (a.k.a. Futures) Functions return a promise - no callback parameter A promise represents an eventual outcome Use a library of functions for transforming and composing promises Promises/A+ specification - http://promises-aplus.github.io/promises-spec when.js (part of cujo.js by SpringSource) is a popular implementation Crockford’s RQ library is another option @crichardson
  • 41. Simpler promise-based code class ProductDetailsService getProductDetails: (productId) -> makeProductDetails = (productInfo, recommendations, reviews) -> productId: productId productDetails: productInfo.entity recommendations: recommendations.entity reviews: reviews.entity responses = [getProductInfo(productId), getRecommendations(productId), getReviews(productId)] getReviews(productId)] all(responses).spread(makeProductDetails) all(responses) spread(makeProductDetails) @crichardson
  • 42. Not bad but lacks Scala’s syntactic sugar class ProductDetailsService .... { def getProductDetails(productId: Long) = { for (((productInfo, recommendations), reviews) <getProductInfo(productId) zip getProductInfo(productId) zip getRecommendations(productId) zip getRecommendations(productId) zip getReviews(productId) getReviews(productId)) yield ProductDetails(productInfo, recommendations, reviews) } } @crichardson
  • 43. Long running computations Long running computation blocks event loop for other requests Need to run outside of main event loop Options: Community: web workers threads Built-in: NodeJS child processes @crichardson
  • 44. Using child processes parent.js var child = require('child_process').fork('child.js'); function sayHelloToChild() { child.send({hello: "child"}); } Create child process Send message to child setTimeout(sayHelloToChild, 1000); child.on('message', function(m) { console.log('parent received:', m); }); function kill() { child.kill(); } setTimeout(kill, 2000); child.js process.on('message', function (m) { console.log("child received message=", m); process.send({ihateyou: "you ruined my life"}) }); @crichardson
  • 45. Modern multi-core machines vs. single-threaded runtime Many components of many applications Don’t need the scalability of the Reactor pattern Request-level thread-based parallelism works fine There are other concurrency options Actors, Software transactional memory, ... Go goroutines, Erlang processes, ... Imposing a single-threaded complexity tax on the entire application is questionable @crichardson
  • 47. Core built-in modules Basic networking HTTP(S) Filesystem Events Timers ...
  • 48. Thousands of community developed modules https://npmjs.org/ web frameworks, SQL/NoSQL database drivers, messaging, utilities... @crichardson
  • 49. What’s a module? foo.js One or more JavaScript files exports.sayHello = function () { console.log(“Hello”); } Optional native code: Compiled during installation JavaScript != systems programming language Package.json - metadata including dependencies @crichardson
  • 50. Easy to install $ npm install package-name --save @crichardson
  • 51. Easy to use Core module OR Path to file OR module in node_modules Module’s exports var http = require(“http”) var server = http.createServer... @crichardson
  • 52. Developing with NodeJS modules Application code Your modules Community modules Core modules @crichardson
  • 53. There is a module for that... Modules + glue code = rapid/easy application development AWESOME!... @crichardson
  • 54. ... BUT Variable quality Multiple incomplete/competing modules, e.g. MySQL drivers without connection pooling! Often abandoned No notion of a Maven-style local repository/cache = repeated downloads ... @crichardson
  • 55. To summarize Flawed and misunderstood JavaScript Rich but variable quality NodeJS Modules Scalable yet costly and often unnecessary Reactor pattern @crichardson
  • 56. How will future history view NodeJS? C++ ? EJB @crichardson
  • 57. Agenda Overview of NodeJS JavaScript: Warts and all The Reactor pattern: an event-driven architecture NodeJS: There is a module for that Building a front-end server with NodeJS @crichardson
  • 58. So why care about NodeJS? Easy to write scalable network services Easy to push events to the browser Easy to get (small) stuff done It has a role to play in modern application architecture @crichardson
  • 59. Evolving from a monolithic architecture.... WAR StoreFrontUI Product Info Service Recommendation Service Review Service Order Service @crichardson
  • 60. ... to a micro-service architecture product info application Product Info Service recommendations application Store front application StoreFrontUI Recommendation Service reviews application Review Service orders application Order Service @crichardson
  • 61. Presentation layer evolution.... WAR StoreFrontUI HTML / HTTP View Controller Browser + JavaScript Model @crichardson
  • 62. ...Presentation layer evolution Browser View Web application Static content Controller JSON-REST Model HTML 5/JavaScript IOS/Android clients Events RESTful Endpoints Event publisher @crichardson
  • 63. Directly connecting the front-end to the backend Chatty API View REST Product Info service REST Recommendation Service AMQP Controller Review service Model Traditional web application View Controller Model Browser/Native App Web unfriendly protocols @crichardson
  • 64. NodeJS as an API gateway Single entry point Browser View Controller NodeJS Model HTML 5 - JavaScript Product Info service REST Recommendation Service AMQP Review service REST proxy Native App View API Gateway REST Controller Model Event publishing Optimized Client specific APIs Protocol translation @crichardson
  • 65. Serving static content with the Express web framework var express = require('express') , http = require('http') , app = express() , server = http.createServer(app) ; From public sub directory app.configure(function(){ ... app.use(express.static(__dirname + '/public')); }); server.listen(8081); @crichardson
  • 67. Proxying to backend server express = require('express') request = require('request') Returns a request handler that proxies to baseUrl app = express.createServer() proxyToBackend = (baseUrl) -> (req, res) -> callback = (error, response, body) -> console.log("error=", error) originRequest = request(baseUrl + req.url, callback) req.pipe(originRequest) originRequest.pipe(res) app.get('/productinfo/*', proxyToBackend('http://productinfo....')) app.get('/recommendations/*', proxyToBackend(''http://recommendations...')) app.get('/reviews/*', proxyToBackend('http://reviews...')) @crichardson
  • 68. Implementing coarsegrained mobile API var express = require('express'), ...; app.get('/productdetails/:productId', function (req, res) { getProductDetails(req.params. productId).then( function (productDetails) { res.json(productDetails); } }); @crichardson
  • 69. Delivering events to the browser @crichardson
  • 70. Socket.io server-side var express = require('express') , http = require('http') , amqp = require(‘amqp’) ....; server.listen(8081); ... var amqpCon = amqp.createConnection(...); Handle socket.io connection io.sockets.on('connection', function (socket) { function amqpMessageHandler(message, headers, deliveryInfo) { Republish var m = JSON.parse(message.data.toString()); socket.emit(‘tick’, m); as socket.io }; event amqpCon.queue(“”, {}, function(queue) { queue.bind(“myExchange”, “”); queue.subscribe(amqpMessageHandler); Subscribe to }); }); AMQP queue https://github.com/cer/nodejs-clock @crichardson
  • 71. Socket.io - client side <html> <body> The event is <span data-bind="text: ticker"></span> <script src="/socket.io/socket.io.js"></script> <script src="/knockout-2.0.0.js"></script> <script src="/clock.js"></script> </body> </html> Bind to model Connect to socket.io clock.js var socket = io.connect(location.hostname); function ClockModel() { self.ticker = ko.observable(1); socket.on('tick', function (data) { self.ticker(data); }); }; ko.applyBindings(new ClockModel()); Subscribe to tick event Update model @crichardson
  • 72. NodeJS is also great for writing backend micro-services “Network elements” Simply ‘route, filter and transform packets’ Have minimal business logic @crichardson
  • 73. NodeJS-powered home security FTP Server Log file FTP Server Upload directory Upload2S3 S3 SQS Queue UploadQueue Processor DynamoDB @crichardson
  • 74. Summary JavaScript is a very flawed language The asynchronous model is often unnecessary; very constraining; and adds complexity BUT despite those problems Today, NodeJS is remarkably useful for building networkfocussed components @crichardson