Node.js vs Play Framework

163
Node.js vs Play Framework VS

description

Video: https://www.youtube.com/watch?v=b6yLwvNSDck Here's the showdown you've been waiting for: Node.js vs Play Framework. Both are popular open source web frameworks that are built for developer productivity, asynchronous I/O, and the real time web. But which one is easier to learn, test, deploy, debug, and scale? Should you pick Javascript or Scala? The Google v8 engine or the JVM? NPM or Ivy? Grunt or SBT? Two frameworks enter, one framework leaves. This is the English version of the presentation. For the version with Japanese subtitles, see http://www.slideshare.net/brikis98/nodejs-vs-play-framework-with-japanese-subtitles

Transcript of Node.js vs Play Framework

Page 1: Node.js vs Play Framework

Node.js vs Play Framework

VS

Page 2: Node.js vs Play Framework

Node.js: server-side JavaScript runtime environment; open source; single threaded; non-blocking I/O.

Page 3: Node.js vs Play Framework

express.js: the most popular web framework for Node.js.

Page 4: Node.js vs Play Framework

Play Framework: Java/Scala web framework; open source; multithreaded; non-blocking I/O.

Page 5: Node.js vs Play Framework

Former Play Tech Lead at LinkedIn. Long time Node.js user.

Yevgeniy Brikman

Page 6: Node.js vs Play Framework

The framework scorecard

Learn

Develop

Test

Secure

Build

Deploy

Debug

Scale

Maintain

Share

Page 7: Node.js vs Play Framework

1

For each feature we discuss...

Much worse than most frameworks

About the same as most frameworks

Much better than most frameworks

510

Page 8: Node.js vs Play Framework

The framework scorecard

Learn

Develop

Test

Secure

Build

Deploy

Debug

Scale

Maintain

Share

Page 9: Node.js vs Play Framework

Node.js: 1-click installers for every OS

Page 10: Node.js vs Play Framework

The “Hello World” Node app: 1 file, 6 lines of code.

var http = require('http');

http.createServer(function (req, res) {

res.writeHead(200, {'Content-Type': 'text/plain'});

res.end('Hello World\n');

}).listen(1337, '127.0.0.1');

console.log('Server running at http://127.0.0.1:1337/');

server.js

Page 11: Node.js vs Play Framework

The “Hello World” Express app: 1 file, 8 lines of code.

var express = require('express');

var app = express();

app.get('/', function(req, res){

res.send('Hello World');

});

var server = app.listen(1337, function() {

console.log('Listening on port %d', server.address().port);

});

server.js

Page 12: Node.js vs Play Framework

Run using node <filename>. Starts instantly!

Page 13: Node.js vs Play Framework

Hit http://localhost:1337 to test

Page 21: Node.js vs Play Framework

Learn

Develop

Test

Secure

Build

The framework scorecard

Deploy

Debug

Scale

Maintain

Share

10

Page 22: Node.js vs Play Framework

Learn

Develop

Test

Secure

Build

The framework scorecard

Deploy

Debug

Scale

Maintain

Share

10

Page 23: Node.js vs Play Framework

Play: download from playframework.com, extract, add activator to your PATH

Page 24: Node.js vs Play Framework

Generate a new app using activator new

Page 25: Node.js vs Play Framework

The “Hello World” Play app: ~35 files and folders

Page 26: Node.js vs Play Framework

Run the app using activator run

Page 27: Node.js vs Play Framework

(Downloading all dependencies can take a while the first time around)

Page 28: Node.js vs Play Framework

Hit http://localhost:9000 to test

Page 33: Node.js vs Play Framework

Learn

Develop

Test

Secure

Build

The framework scorecard

Deploy

Debug

Scale

Maintain

Share

10 7

Page 34: Node.js vs Play Framework

Learn

Develop

Test

Secure

Build

The framework scorecard

Deploy

Debug

Scale

Maintain

Share

10 7

Page 35: Node.js vs Play Framework

Routing

GET clients/:id Clients.show(id: Long)

def show(id: Long) = Action { request =>

getClient(id).map { client =>

Ok(views.html.clients.show(client))

}

}

app.get('clients/:id', function(req, res) {

getClient(req.params.id, function(client) {

res.render('show', client);

});

});

RESTful routing. Extracts query & path params.

RESTful routing. Extracts query & path params. Type safe. Actions are composable. Reverse routing.

Page 36: Node.js vs Play Framework

Templates

@(name: String, headline: String)

<div class="client">

<h1>@name</h1>

<div class="headline">

Headline: @headline

</div>

</div>

<div class="client">

<h1>{{name}}</h1>

<div class="headline">

Headline: {{headline}}

</div>

</div>

Many template options: handlebars, mustache, dust, jade, etc. Most support client-side rendering!

Twirl templates are compiled into Scala functions: type safe and composable! Other template types via plugins.

Page 37: Node.js vs Play Framework

i18n

Translations: i18next-node, i18n-node. Formatting: moment.js, numeral.js.

Translations: Play i18n API. Formatting: Java formatting libraries.

<div class="client">

<h1>{{name}}</h1>

<div class="headline">

{{t "headline.label" headline=headline}}

</div>

</div>

@(name: String, headline: String)

<div class="client">

<h1>@name</h1>

<div class="headline">

Messages("headline.label", headline)

</div>

</div>

Page 38: Node.js vs Play Framework

Form binding and validation

Forms, node-formidable, validator.js. Play form binding and validation API.

var regForm = forms.create({

name: fields.string({required: true}),

age: fields.number({min: 18})

});

regForm.handle(req, {

success: function(form) { ... },

error: function(form) { ... }

});

val regForm = Form(mapping(

"name" -> nonEmptyText,

"age" -> number(min = 18)

)(UserData.apply)(UserData.unapply))

regForm.bindFromRequest.fold(

err => BadRequest("Validation error"),

data => Ok(s"Hi $data.name!")

)

Page 39: Node.js vs Play Framework

JSON, XML, File Upload

bodyParser, xml2js, node-formidable. Play JSON, XML, File Upload APIs.

// Automatically parse application/json body

app.use(bodyParser.json());

app.post('/clients', function (req, res, next) {

var name = req.body.name;

var age = req.body.age;

res.send(name + " is " + age + " years old.");

});

case class Person(name: String, age: Int)

implicit val prsnFmt = Json.format[Person]

def create = Action(parse.json) { request =>

val person = request.body.as[Person]

Ok(s"$person.name is $person.age years old")

}

POST /clients Clients.create

Page 40: Node.js vs Play Framework

Data

Slick, Anorm, Ebean, JPAMySQL, MariaDB, PostgreSLQ, SQLite, Oracle, SQL Server,

DB2, Derby, H2SQLSequelize, Bookshelf.js, node-orm2

MySQL, MariaDB, PostgreSQL, SQLite

NoSQLmongojs/mongoose, cassandra-client, cradle/nano, node_redis, node-neo4j

MongoDB, Cassandra, CouchDB, Redis, Neo4j

ReactiveMongo, DataStax, sprouch, play-plugins-redis, Neo4j-play, JPA

MongoDB, Cassandra, CouchDB, Redis, Neo4j

Cachingnode-memcached, connect-cachememcached, in-memory (not recommended)

play2-memcached, memcontinuationed, Play Cache, ehcache, Guava

memcached, in-memory

Schemasnode-db-migrate, node-migrate Play database evolutions

Page 41: Node.js vs Play Framework

Real-time web

socket.io: server & client APIs; WebSockets, Flash Sockets, polling, etc.

Play WebSockets, Comet, and EventSource APIs. Server-side only.

// server code

io.on('connection', function (socket) {

socket.emit('msg', 'Server says hi!');

socket.on('msg', function (msg) { … });

});

def chat = WebSocket.acceptWithActor {

request => out => Props(new Chat(out))

}

class Chat(out: ActorRef) extends Actor {

def receive = {

case m: String => out ! s"Got msg: $m"

}

}

// client code

socket.emit('msg', 'Client says hi!');

socket.on('msg', function (msg) { … });

Page 42: Node.js vs Play Framework

● Play is a full stack framework● Express.js is a minimal framework

● You need plugins for most tasks

● Finding good plugins takes time

● Gluing plugins together takes time

● There are defaults for most tasks

● Defaults are mostly high quality

● All defaults can be replaced

Page 43: Node.js vs Play Framework

Learn

Develop

Test

Secure

Build

The framework scorecard

Deploy

Debug

Scale

Maintain

Share

10 7

8 10

Page 44: Node.js vs Play Framework

Learn

Develop

Test

Secure

Build

The framework scorecard

Deploy

Debug

Scale

Maintain

Share

10 7

8 10

Page 46: Node.js vs Play Framework

Functional testing: use supertest or call server.listen directly.

var request = require('supertest')

, app = require('express')();

app.get('/user', function(req, res){

res.send(200, { name: 'tobi' });

});

request(app)

.get('/user')

.expect('Content-Type', /json/)

.expect(200);

Page 48: Node.js vs Play Framework

Code coverage: Istanbul or Blanket.js

Page 49: Node.js vs Play Framework

Learn

Develop

Test

Secure

Build

The framework scorecard

Deploy

Debug

Scale

Maintain

Share

10 7

8 10

10

Page 50: Node.js vs Play Framework

Learn

Develop

Test

Secure

Build

The framework scorecard

Deploy

Debug

Scale

Maintain

Share

10 7

8 10

10

Page 52: Node.js vs Play Framework

Functional testing: use Play’s built-in functional test helpers.

"respond to the index Action" in new App(FakeApplication()) {

val Some(result) = route(FakeRequest(GET, "/Bob"))

status(result) mustEqual OK

contentType(result) mustEqual Some("text/html")

charset(result) mustEqual Some("utf-8")

contentAsString(result) must include ("Hello Bob")

}

Page 53: Node.js vs Play Framework

UI testing: use Play’s built-in integration test helpers and built-in Selenium support.

class ExampleSpec extends PlaySpec with OneServerPerSuite with OneBrowserPerSuite {

"The OneBrowserPerTest trait" must {

"provide a web driver" in {

go to (s"http://localhost:$port/testing")

pageTitle mustBe "Test Page"

click on find(name("b")).value

eventually { pageTitle mustBe "scalatest" }

}

}

}

Page 54: Node.js vs Play Framework

Code coverage: jacoco4sbt or scct

Page 55: Node.js vs Play Framework

Learn

Develop

Test

Secure

Build

The framework scorecard

Deploy

Debug

Scale

Maintain

Share

10 7

8 10

10 10

Page 56: Node.js vs Play Framework

Learn

Develop

Test

Secure

Build

The framework scorecard

Deploy

Debug

Scale

Maintain

Share

10 7

8 10

10 10

Page 58: Node.js vs Play Framework

Learn

Develop

Test

Secure

Build

The framework scorecard

Deploy

Debug

Scale

Maintain

Share

10 7

8 10

10 10

86

Page 59: Node.js vs Play Framework

Learn

Develop

Test

Secure

Build

The framework scorecard

Deploy

Debug

Scale

Maintain

Share

10 7

8 10

10 10

86

Page 60: Node.js vs Play Framework

Node.js uses NPM to manage dependencies and basic build commands

{

"name": "Hello World App",

"version": "0.0.3",

"dependencies": {

"express": "4.8.0",

"underscore": "1.6.0"

},

"scripts": {

"test": "node tests/run.js",

"lint": "jshint src"

}

}

Page 61: Node.js vs Play Framework

Many options available for more complicated builds: grunt.js, gulp.js, or broccoli

Page 62: Node.js vs Play Framework

Thousands of plugins for all common build tasks

Page 63: Node.js vs Play Framework

Learn

Develop

Test

Secure

Build

The framework scorecard

Deploy

Debug

Scale

Maintain

Share

10 7

8 10

10 10

86

10

Page 64: Node.js vs Play Framework

Learn

Develop

Test

Secure

Build

The framework scorecard

Deploy

Debug

Scale

Maintain

Share

10 7

8 10

10 10

86

10

Page 65: Node.js vs Play Framework

Play uses SBT as the build system. SBT is an interactive build system.

Page 66: Node.js vs Play Framework

In SBT, build definitions are written in Scala! … But the learning curve is very steep.

object AppBuild extends Build {

lazy val root = Project(id = "root", base = file(".")).settings(

name := "test-play-app",

version := version,

libraryDependencies += Seq(

"org.scala-tools" % "scala-stm_2.11.1" % "0.3",

"org.apache.derby" % "derby" % "10.4.1.3"

)

)

def version = Option(System.getProperty("version")).getOrElse("0.0.3")

}

Page 67: Node.js vs Play Framework

Dependencies are managed using Ivy: familiar, but slow.

Page 68: Node.js vs Play Framework

Play uses sbt-web to build static content: few plugins; depends on Rhino (slow) or node.js (!).

Page 69: Node.js vs Play Framework

Learn

Develop

Test

Secure

Build

The framework scorecard

Deploy

Debug

Scale

Maintain

Share

10 7

8 10

10 10

86

10 7

Page 70: Node.js vs Play Framework

Learn

Develop

Test

Secure

Build

The framework scorecard

Deploy

Debug

Scale

Maintain

Share

10 7

8 10

10 10

86

10 7

Page 73: Node.js vs Play Framework

Use cluster to run one node instance per CPU

if (cluster.isMaster) {

for (var i = 0; i < numCPUs; i++) {

cluster.fork(); // Fork workers

}

cluster.on('exit', function(worker, code, signal) {

console.log('worker ' + worker.process.pid + ' died');

});

} else {

http.createServer(function(req, res) {

// ...

}).listen(8000);

}

Page 75: Node.js vs Play Framework

Configuration: node-config or nconf

var config = require('config');

var host = config.get('dbConfig.host');

{

"dbConfig": {

"host": "localhost",

"port": 5984,

"dbName": "customers"

}

}

server.js

config/default.json

Page 76: Node.js vs Play Framework

Use nginx, apache, or ATS to load balance, serve static content, terminate SSL

Client

Data Center

Reverse proxy(e.g. nginx) DB

Static server(e.g. nginx)

Node instanceNode

instanceNode instanceNode

instanceNode instance

Node instanceNode

instanceNode instanceNode

instance

Node instanceNode

instanceNode instanceNode

instance

Page 77: Node.js vs Play Framework

Learn

Develop

Test

Secure

Build

The framework scorecard

Deploy

Debug

Scale

Maintain

Share

10 7

8 10

10 10

86

10 7

8

Page 78: Node.js vs Play Framework

Learn

Develop

Test

Secure

Build

The framework scorecard

Deploy

Debug

Scale

Maintain

Share

10 7

8 10

10 10

86

10 7

8

Page 81: Node.js vs Play Framework

Use the SBT Native Packager to package the app as tgz, deb, RPM, etc.

Page 82: Node.js vs Play Framework

Configuration: Play comes with Typesafe Config

val host = Play.current.configuration.getString("dbConfig.host")

dbConfig = {

host: "localhost",

port: 5984,

dbName: "customers"

}

app/controllers/Application.scala

conf/application.conf

Page 83: Node.js vs Play Framework

Use nginx, apache, or ATS to load balance, serve static content, terminate SSL

Client

Data Center

Reverse proxy(e.g. nginx)

Play app

DB

Static server(e.g. nginx)

Play app

Play app

Page 84: Node.js vs Play Framework

Learn

Develop

Test

Secure

Build

The framework scorecard

Deploy

Debug

Scale

Maintain

Share

10 7

8 10

10 10

86

10 7

8 7

Page 85: Node.js vs Play Framework

Learn

Develop

Test

Secure

Build

The framework scorecard

Deploy

Debug

Scale

Maintain

Share

10 7

8 10

10 10

86

10 7

8 7

Page 88: Node.js vs Play Framework

Use winston, log4js, or bunyan for logging

var winston = require("winston");

winston.info("CHILL WINSTON! ... I put it in the logs.");

Page 89: Node.js vs Play Framework

Learn

Develop

Test

Secure

Build

The framework scorecard

Deploy

Debug

Scale

Maintain

Share

10 7

8 10

10 10

86

10 7

8 7

10

Page 90: Node.js vs Play Framework

Learn

Develop

Test

Secure

Build

The framework scorecard

Deploy

Debug

Scale

Maintain

Share

10 7

8 10

10 10

86

10 7

8 7

10

Page 91: Node.js vs Play Framework

Play runs on the JVM, so you can use your favorite IDE to debug: IntelliJ, Eclipse, NetBeans

Page 92: Node.js vs Play Framework

In dev, Play shows errors right in the browser

Page 95: Node.js vs Play Framework

Learn

Develop

Test

Secure

Build

The framework scorecard

Deploy

Debug

Scale

Maintain

Share

10 7

8 10

10 10

86

10 7

8 7

10 10

Page 96: Node.js vs Play Framework

Learn

Develop

Test

Secure

Build

The framework scorecard

Deploy

Debug

Scale

Maintain

Share

10 7

8 10

10 10

86

10 7

8 7

10 10

Page 97: Node.js vs Play Framework

Part 1: scaling for lots of traffic

Page 98: Node.js vs Play Framework

TechEmpower benchmarks. Warning: microbenchmarks are not a substitute for real world perf testing!

Page 102: Node.js vs Play Framework

LinkedIn experience #1: Play and Node.js are very fast in a service oriented architecture with NIO.

Internet Load Balancer

Frontend Server

Frontend Server

Frontend Server

Backend Server

Backend Server

Backend Server

Backend Server

Backend Server

Data Store

Data Store

Data Store

Data Store

Page 103: Node.js vs Play Framework

LinkedIn experience #2: Play is ok with blocking I/O & CPU/memory bound use cases. Node.js is not.

// BAD: write files synchronously

fs.writeFileSync('message.txt', 'Hello Node');

console.log("It's saved, but you just blocked ALL requests!");

// Good: write files asynchronously

fs.writeFile('message.txt', 'Hello Node', function (err) {

console.log("It's saved and the server remains responsive!");

});

Page 104: Node.js vs Play Framework

Part 2: scaling for large teams and projects

Page 105: Node.js vs Play Framework

Node.js: best for small projects, short projects, small teams.

Page 106: Node.js vs Play Framework

Play: best for longer projects. Slower ramp up, but scales well with team and project size.

Page 107: Node.js vs Play Framework

For comparison: Spring MVC

Page 108: Node.js vs Play Framework

Learn

Develop

Test

Secure

Build

The framework scorecard

Deploy

Debug

Scale

Maintain

Share

10 7

8 10

10 10

86

10 7

8 7

10

10

10

10

Page 109: Node.js vs Play Framework

Learn

Develop

Test

Secure

Build

The framework scorecard

Deploy

Debug

Scale

Maintain

Share

10 7

8 10

10 10

86

10 7

8 7

10

10

10

10

Page 110: Node.js vs Play Framework

Maintenance: the good parts

Page 111: Node.js vs Play Framework

Functional programming: first class functions, closures, underscore.js

Page 112: Node.js vs Play Framework

JavaScript is ubiquitous...

Page 113: Node.js vs Play Framework

...Which means you can share developers, practices, and even code: rendr, derby, meteor

Page 114: Node.js vs Play Framework

Node core is (mostly) stable and mature. Bugs, regressions, and backwards incompatibility are rare.

Page 115: Node.js vs Play Framework

Maintenance: the bad parts

Page 116: Node.js vs Play Framework
Page 117: Node.js vs Play Framework

'' == '0' // false

0 == '' // true

0 == '0' // true

false == 'false' // false

false == '0' // true

false == undefined // false

false == null // false

null == undefined // true

' \t\r\n ' == 0 // true

Bad Parts

Page 118: Node.js vs Play Framework

// Default scope is global

var foo = "I'm a global variable!"

// Setting undeclared variables puts them in global scope too

bar = "I'm also a global variable!";

if (foo) {

// Look ma, no block scope!

var baz = "Believe it or not, I'll also be a global variable!"

}

Awful Parts

Page 121: Node.js vs Play Framework

doSomethingAsync(req1, function(err1, res1) {

doSomethingAsync(req2, function(err2, res2) {

doSomethingAsync(req3, function(err3, res3) {

doSomethingAsync(req4, function(err4, res4) {

// ...

});

});

});

});

Callback hell: control flow, error handling, and composition are all difficult

Page 122: Node.js vs Play Framework

Many NPM packages are NOT stable or mature.Incompatibility + bugs + dynamic typing = pain.

Page 123: Node.js vs Play Framework

Learn

Develop

Test

Secure

Build

The framework scorecard

Deploy

Debug

Scale

Maintain

Share

10 7

8 10

10 10

86

10 7

8 7

10

10

10

10

3

Page 124: Node.js vs Play Framework

Learn

Develop

Test

Secure

Build

The framework scorecard

Deploy

Debug

Scale

Maintain

Share

10 7

8 10

10 10

86

10 7

8 7

10

10

10

10

3

Page 125: Node.js vs Play Framework

Maintenance: the good parts

Page 126: Node.js vs Play Framework

Functional programming

def sort(a: List[Int]): List[Int] = {

if (a.length < 2) a

else {

val pivot = a(a.length / 2)

sort(a.filter(_ < pivot)) :::

a.filter(_ == pivot) :::

sort(a.filter(_ > pivot))

}

}

Page 127: Node.js vs Play Framework

Powerful type system

Page 128: Node.js vs Play Framework

Very expressive: case classes, pattern matching, lazy, option, implicits

val NameTagPattern = "Hello, my name is (.+) (.+)".r

val ListPattern = "Last: (.+). First: (.+).".r

// Case classes automatically generate immutable fields, equals, hashCode, constructor

case class Name(first: String, last: String)

// Use Option to avoid returning null if there is no name found

def extractName(str: String): Option[Name] = {

Option(str).collectFirst {

// Pattern matching on regular expressions

case NameTagPattern(fname, lname) => Name(fname, lname)

case ListPattern(lname, fname) => Name(fname, lname)

}

}

Page 129: Node.js vs Play Framework

Runs on the JVM; interop with Java.

Page 131: Node.js vs Play Framework

No callback hell!

def index = Action {

// Make 3 sequential, async calls

for {

foo <- WS.url(url1).get()

bar <- WS.url(url2).get()

baz <- WS.url(url3).get()

} yield {

// Build a result using foo, bar, and baz

}

}

Page 132: Node.js vs Play Framework

Good IDE support

Page 133: Node.js vs Play Framework

Maintenance: the bad parts

Page 134: Node.js vs Play Framework

Slow compiler

Page 135: Node.js vs Play Framework

Fortunately, Play/SBT support incremental compilation and hot reload!

Page 136: Node.js vs Play Framework

Complexity

Page 137: Node.js vs Play Framework

More complexity

Page 138: Node.js vs Play Framework

Play is stable, but not mature: backwards incompatible API changes every release.

Page 139: Node.js vs Play Framework

Even worse: Scala is not binary compatible between releases!

Page 140: Node.js vs Play Framework

Backwards incompatibility = pain.… Static typing makes it a little more manageable.

Page 141: Node.js vs Play Framework

Learn

Develop

Test

Secure

Build

The framework scorecard

Deploy

Debug

Scale

Maintain

Share

10 7

8 10

10 10

86

10 7

8 7

10

10

10

10

3 8

Page 142: Node.js vs Play Framework

Learn

Develop

Test

Secure

Build

The framework scorecard

Deploy

Debug

Scale

Maintain

Share

10 7

8 10

10 10

86

10 7

8 7

10

10

10

10

3 8

Page 143: Node.js vs Play Framework

351Contributors544

Watchers2,376 576

Stars31,332 5,077

Github activity as of 08/10/14

Forks6,970 1,872

PR’s3,066 2,201

Page 144: Node.js vs Play Framework

10,698StackOverflow Questions53,555

Google Group Members14,199 11,577

Google Group Posts/Month ~400 ~1,100

StackOverflow, mailing list activity as of 08/12/14

Page 146: Node.js vs Play Framework

88,000 packages in NPM ~80 Play Modules

Page 147: Node.js vs Play Framework

88,000 packages in NPM 83,000 artifacts in Maven

Page 148: Node.js vs Play Framework

Joyent offers commercial support for Node.js

Typesafe offers commercial support for Play

Page 152: Node.js vs Play Framework

9,037LinkedIn82,698

Indeed2,267 206

CareerBuilder447 30

Candidates as of 08/13/14

Page 153: Node.js vs Play Framework

Learn

Develop

Test

Secure

Build

The framework scorecard

Deploy

Debug

Scale

Maintain

Share

10 7

8 10

10 10

86

10 7

8 7

10

10

10

10

3 8

10 7

Page 154: Node.js vs Play Framework

Learn

Develop

Test

Secure

Build

The framework scorecard

Deploy

Debug

Scale

Maintain

Share

10 7

8 10

10 10

86

10 7

8 7

10

10

10

10

3 8

10 7

Page 155: Node.js vs Play Framework

Final score

85

84

Page 156: Node.js vs Play Framework

Final score

85

84

Page 157: Node.js vs Play Framework
Page 158: Node.js vs Play Framework

Both frameworks are great. Decide based on strengths/weakness, not my arbitrary score!

Page 159: Node.js vs Play Framework

1. You’re building small apps with small teams

2. You already have a bunch of JavaScript ninjas

3. Your app is mostly client-side JavaScript

4. Your app is mostly real-time

5. Your app is purely I/O bound

Use node.js if:

Page 160: Node.js vs Play Framework

1. You don’t write lots of automated tests

2. Your code base or team is going to get huge

3. You do lots of CPU or memory intensive tasks

Don’t use node.js if:

Page 161: Node.js vs Play Framework

1. You’re already using the JVM

2. You like type safety and functional programming

3. Your code base or team is going to get big

4. You want a full stack framework

5. You need flexibility: non-blocking I/O, blocking I/O, CPU intensive tasks, memory intensive tasks

Use Play if:

Page 162: Node.js vs Play Framework

1. You don’t have time to master Play, Scala, and SBT

2. You hate functional programming or static typing

Don’t use Play if:

Page 163: Node.js vs Play Framework

Questions?