Node.js vs Play Framework (with Japanese subtitles)

Embed Size (px)


Video: 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 version of the presentation has Japanese subtitles. For the English only version, see

Text of Node.js vs Play Framework (with Japanese subtitles)

  • 1. VSNode.js vs Play Framework

2. Node.js: server-side JavaScript runtime environment;open source; single threaded; non-blocking I/O.Node.js: JSOSSI/O 3. express.js: the most popular webframework for Node.js Web 4. Play Framework: Java/Scala web framework; opensource; multithreaded; non-blocking I/O.Play: Java/Scala WebOSSI/O 5. Yevgeniy BrikmanFormer Play Tech Lead at LinkedIn. Long time Node.js user.LinkedInPlay Tech LeadNode.js 6. The framework scorecardLearnDevelopTestSecureBuildDeployDebugScaleMaintainShare 7. For each feature we discuss...1Much worse than most frameworksAbout the same as most frameworksMuch better than most frameworks5101 = 5 = 10 = 8. The framework scorecardLearnDevelopTestSecureBuildDeployDebugScaleMaintainShare 9. Node.js: 1-click installers for every OSOS 10. var http = require('http');http.createServer(function (req, res) {res.writeHead(200, {'Content-Type': 'text/plain'});res.end('Hello Worldn');}).listen(1337, '');console.log('Server running at');server.jsThe Hello World Node app: 1 file, 6 lines of code. 11. 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.jsThe Hello World Express app: 1 file, 8 lines of code. 12. Run using node . Starts instantly! 13. Hit http://localhost:1337 to test 14. 15. Node Beginner Book, Mastering Node.js,Node: Up and Running, Node.js in Action 16. Node API Docs 17. Express.js guide 18. Express Web Application Development Express.js Guide 19. Express.js API docs 20. And much, much moreTons of resources; very gradual learning curve. 21. LearnDevelopTestSecureBuildThe framework scorecardDeployDebugScaleMaintainShare10 22. LearnDevelopTestSecureBuildThe framework scorecardDeployDebugScaleMaintainShare10 23. Play: download from,extract, add activator to your PATHPlayactivator PATH 24. Generate a new app using activator new 25. The Hello World Play app: ~35 files and folders 26. Run the app using activator run 27. (Downloading all dependencies can take awhile the first time around)jar 28. Hit http://localhost:9000 to test 29. Play Framework Documentation 30. Activator Templates 31. Play for Scala Learning Play Framework 2 32. Ultimate Guide to Getting Started with Play.Not as many resources; steep learning curve. 33. LearnDevelopTestSecureBuildThe framework scorecardDeployDebugScaleMaintainShare10 7 34. LearnDevelopTestSecureBuildThe framework scorecardDeployDebugScaleMaintainShare10 7 35. GET clients/:id Long)def show(id: Long) = Action { request =>getClient(id).map { client =>Ok(}}Routingapp.get('clients/:id', function(req, res) {getClient(, function(client) {res.render('show', client);});});RESTful routing. Extracts query & pathparams.RESTful routing. Extracts query & pathparams. Type safe. Actions arecomposable. Reverse routing. 36. @(name: String, headline: String)

Headline: @headline


Headline: {{headline}}

Many template options: handlebars,mustache, dust, jade, etc. Most supportclient-side rendering!Twirl templates are compiled into Scalafunctions: type safe and composable!Other template types via plugins. 37. i18nTranslations: i18next-node, i18n-node.Formatting: moment.js, numeral.js.Translations: Play i18n API.Formatting: Java formatting libraries.

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

@(name: String, headline: String)

Messages("headline.label", headline)

38. var regForm = forms.create({name: fields.string({required: true}),age: fields.number({min: 18})Forms, node-formidable, validator.js. Play form binding and validation API.Form binding and validation});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 $!")) 39. // Automatically parse application/json bodyapp.use(bodyParser.json());'/clients', function (req, res, next) {var name =;var age = req.body.age;res.send(name + " is " + age + " years old.");});POST /clients Clients.createcase class Person(name: String, age: Int)implicit val prsnFmt = Json.format[Person]def create = Action(parse.json) { request =>val person =[Person]Ok(s"$ is $person.age years old")}bodyParser, xml2js, node-formidable. Play JSON, XML, File Upload APIs.JSON, XML, File Upload 40. DataSlick, Anorm, Ebean, JPAMySQL, MariaDB, PostgreSLQ, SQLite, Oracle, SQL Server,DB2, Derby, H2Sequelize, Bookshelf.js, node-orm2 SQLMySQL, MariaDB, PostgreSQL, SQLiteNoSQLmongojs/mongoose, cassandra-client,cradle/nano, node_redis, node-neo4jMongoDB, Cassandra, CouchDB, Redis, Neo4jReactiveMongo, DataStax, sprouch, play-plugins-redis, Neo4j-play, JPAMongoDB, Cassandra, CouchDB, Redis, Neo4jnode-memcached, connect-cache Cachingmemcached, in-memory (not recommended)play2-memcached, memcontinuationed,Play Cache, ehcache, Guavamemcached, in-memorynode-db-migrate, node-migrate Schemas Play database evolutions 41. server & client APIs;WebSockets, Flash Sockets, polling, etc.Play WebSockets, Comet, andEventSource APIs. Server-side only.Real-time web// server codeio.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 codesocket.emit('msg', 'Client says hi!');socket.on('msg', function (msg) { }); 42. Express.js is a minimal framework Play is a full stack 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 replacedExpress.jsPlay 43. LearnDevelopTestSecureBuildThe framework scorecardDeployDebugScaleMaintainShare10 78 10 44. LearnDevelopTestSecureBuildThe framework scorecardDeployDebugScaleMaintainShare10 78 10 45. Unit testing: Jasmine, Mocha, QUnit,nodeunit, Expresso or Vows 46. 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);Functional testing: use supertest or callserver.listen directly. 47. UI testing: phantom.js or zombie.js 48. Code coverage: Istanbul or Blanket.js 49. LearnDevelopTestSecureBuildThe framework scorecardDeployDebugScaleMaintainShare10 78 1010 50. LearnDevelopTestSecureBuildThe framework scorecardDeployDebugScaleMaintainShare10 78 1010 51. Unit testing: junit, ScalaTest, specs2, or testng 52. "respond to the index Action" in new App(FakeApplication()) {val Some(result) = route(FakeRequest(GET, "/Bob"))status(result) mustEqual OKcontentType(result) mustEqual Some("text/html")charset(result) mustEqual Some("utf-8")contentAsString(result) must include ("Hello Bob")}Functional testing: use Plays built-infunctional test helpers. 53. 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")).valueeventually { pageTitle mustBe "scalatest" }}}}UI testing: use Plays built-in integration testhelpers and built-in Selenium support. 54. Code coverage: jacoco4sbt or scct 55. LearnDevelopTestSecureBuildThe framework scorecardDeployDebugScaleMaintainShare10 78 1010 10 56. LearnDevelopTestSecureBuildThe framework scorecardDeployDebugScaleMaintainShare10 78 1010 10 57. (not enabled by default!) Connect CSRF Middleware CSRF(not enabled by default!)Depends on template engine XSS Twirl escapes correctlyVulnerabilities: eval, setTimeout, InjectionSecurityCSRFFiltersetInterval, new Function Few vulnerabilities of this sortHelmet middleware Headers SecurityHeadersFilterpassport.js, everyauth Auth SecureSocial, deadbolt, play-authenticateNode Security Project Advisories Play Security Vulnerabilities 58. LearnDevelopTestSecureBuildThe framework scorecardDeployDebugScaleMaintainShare10 78 1010 106 8 59. LearnDevelopTestSecureBuildThe framework scorecardDeployDebugScaleMaintainShare10 78 1010 106 8 60. {"name": "Hello World App","version": "0.0.3","dependencies": {"express": "4.8.0","underscore": "1.6.0"},"scripts": {"test": "node tests/run.js"}}Node.js uses NPM to manage dependencies andbasic build commandsNode.jsNPM 61. Many options available for more complicatedbuilds: grunt.js, gulp.js, or broccoligrunt.js, gulp.js, broccoli 62. Thousands of plugins for all common build tasks 63. LearnDevelopTestSecureBuildThe framework scorecardDeployDebugScaleMaintainShare10 78 1010 106 810 64. LearnDevelopTestSecureBuildThe framework scorecardDeployDebugScaleMaintainShare10 78 1010 106 810 65. Play uses SBT as the build system. SBT is aninteractive build system.Play SBT 66. 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" % ""))def version = Option(System.getProperty("version")).getOrElse("0.0.3")}In SBT, build definitions are written in Scala! But the learning curve is very steep.Scala 67. Dependenci