Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Node.js vs Play Framework (with Japanese subtitles)

37,597 views

Published on

Video: http://www.nicovideo.jp/watch/1410857293

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 http://www.slideshare.net/brikis98/nodejs-vs-play-framework

Published in: Software

Node.js vs Play Framework (with Japanese subtitles)

  1. 1. VS Node.js vs Play Framework
  2. 2. Node.js: server-side JavaScript runtime environment; open source; single threaded; non-blocking I/O. Node.js: サーバサイドJSランタイム、OSS、シングルスレッド、非同期I/O
  3. 3. express.js: the most popular web framework for Node.js. express.js: Node.js で一番人気のWebフレームワーク
  4. 4. Play Framework: Java/Scala web framework; open source; multithreaded; non-blocking I/O. Play: Java/Scala Webフレームワーク、OSS、マルチスレッド、非同期I/O
  5. 5. Yevgeniy Brikman Former Play Tech Lead at LinkedIn. Long time Node.js user. 元LinkedIn社Play Tech Lead。ベテランNode.jsユーザ
  6. 6. The framework scorecard Learn Develop Test Secure Build Deploy Debug Scale Maintain Share
  7. 7. For each feature we discuss... 1 Much worse than most frameworks About the same as most frameworks Much better than most frameworks 5 10 1 = 酷い、5 = 平均的、10 = 優秀
  8. 8. The framework scorecard Learn Develop Test Secure Build Deploy Debug Scale Maintain Share
  9. 9. Node.js: 1-click installers for every OS OSにかかわらずインストーラは万全
  10. 10. var http = require('http'); http.createServer(function (req, res) { res.writeHead(200, {'Content-Type': 'text/plain'}); res.end('Hello Worldn'); }).listen(1337, '127.0.0.1'); console.log('Server running at http://127.0.0.1:1337/'); server.js The “Hello World” Node app: 1 file, 6 lines of code.
  11. 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.js The “Hello World” Express app: 1 file, 8 lines of code.
  12. 12. Run using node <filename>. Starts instantly!
  13. 13. Hit http://localhost:1337 to test
  14. 14. nodeschool.io
  15. 15. Node Beginner Book, Mastering Node.js, Node: Up and Running, Node.js in Action
  16. 16. Node API Docs
  17. 17. Express.js guide
  18. 18. Express Web Application Development Express.js Guide
  19. 19. Express.js API docs
  20. 20. And much, much more Tons of resources; very gradual learning curve. リソースが豊富、緩やかな学習曲線
  21. 21. Learn Develop Test Secure Build The framework scorecard Deploy Debug Scale Maintain Share 10
  22. 22. Learn Develop Test Secure Build The framework scorecard Deploy Debug Scale Maintain Share 10
  23. 23. Play: download from playframework.com, extract, add activator to your PATH Play:ダウンロードし、展開し、activator をPATH に追加する
  24. 24. Generate a new app using activator new
  25. 25. The “Hello World” Play app: ~35 files and folders
  26. 26. Run the app using activator run
  27. 27. (Downloading all dependencies can take a while the first time around) 初回はjarのダウンロードに時間がかかる
  28. 28. Hit http://localhost:9000 to test
  29. 29. Play Framework Documentation
  30. 30. Activator Templates
  31. 31. Play for Scala Learning Play Framework 2
  32. 32. Ultimate Guide to Getting Started with Play. Not as many resources; steep learning curve. リソースが少なめ、急勾配の学習曲線
  33. 33. Learn Develop Test Secure Build The framework scorecard Deploy Debug Scale Maintain Share 10 7
  34. 34. Learn Develop Test Secure Build The framework scorecard Deploy Debug Scale Maintain Share 10 7
  35. 35. GET clients/:id Clients.show(id: Long) def show(id: Long) = Action { request => getClient(id).map { client => Ok(views.html.clients.show(client)) } } Routing 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.
  36. 36. @(name: String, headline: String) <div class="client"> <h1>@name</h1> <div class="headline"> Headline: @headline </div> </div> Templates <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.
  37. 37. 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>
  38. 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 $data.name!") )
  39. 39. // 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."); }); POST /clients Clients.create 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") } bodyParser, xml2js, node-formidable. Play JSON, XML, File Upload APIs. JSON, XML, File Upload
  40. 40. Data Slick, Anorm, Ebean, JPA MySQL, MariaDB, PostgreSLQ, SQLite, Oracle, SQL Server, DB2, Derby, H2 Sequelize, Bookshelf.js, node-orm2 SQL MySQL, MariaDB, PostgreSQL, SQLite NoSQL mongojs/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 node-memcached, connect-cache Caching memcached, in-memory (not recommended) play2-memcached, memcontinuationed, Play Cache, ehcache, Guava memcached, in-memory node-db-migrate, node-migrate Schemas Play database evolutions
  41. 41. socket.io: server & client APIs; WebSockets, Flash Sockets, polling, etc. Play WebSockets, Comet, and EventSource APIs. Server-side only. Real-time web // 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) { … });
  42. 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 replaced Express.js:ミニマル、プラグインを多く使う。Play:フルスタック
  43. 43. Learn Develop Test Secure Build The framework scorecard Deploy Debug Scale Maintain Share 10 7 8 10
  44. 44. Learn Develop Test Secure Build The framework scorecard Deploy Debug Scale Maintain Share 10 7 8 10
  45. 45. Unit testing: Jasmine, Mocha, QUnit, nodeunit, Expresso or Vows
  46. 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 call server.listen directly.
  47. 47. UI testing: phantom.js or zombie.js
  48. 48. Code coverage: Istanbul or Blanket.js
  49. 49. Learn Develop Test Secure Build The framework scorecard Deploy Debug Scale Maintain Share 10 7 8 10 10
  50. 50. Learn Develop Test Secure Build The framework scorecard Deploy Debug Scale Maintain Share 10 7 8 10 10
  51. 51. Unit testing: junit, ScalaTest, specs2, or testng
  52. 52. "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") } Functional testing: use Play’s built-in functional test helpers.
  53. 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")).value eventually { pageTitle mustBe "scalatest" } } } } UI testing: use Play’s built-in integration test helpers and built-in Selenium support.
  54. 54. Code coverage: jacoco4sbt or scct
  55. 55. Learn Develop Test Secure Build The framework scorecard Deploy Debug Scale Maintain Share 10 7 8 10 10 10
  56. 56. Learn Develop Test Secure Build The framework scorecard Deploy Debug Scale Maintain Share 10 7 8 10 10 10
  57. 57. (not enabled by default!) Connect CSRF Middleware CSRF (not enabled by default!) Depends on template engine XSS Twirl escapes correctly Vulnerabilities: eval, setTimeout, Injection Security CSRFFilter setInterval, new Function Few vulnerabilities of this sort Helmet middleware Headers SecurityHeadersFilter passport.js, everyauth Auth SecureSocial, deadbolt, play-authenticate Node Security Project Advisories Play Security Vulnerabilities
  58. 58. Learn Develop Test Secure Build The framework scorecard Deploy Debug Scale Maintain Share 10 7 8 10 10 10 6 8
  59. 59. Learn Develop Test Secure Build The framework scorecard Deploy Debug Scale Maintain Share 10 7 8 10 10 10 6 8
  60. 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 and basic build commands Node.jsは依存性管理や簡単なコマンド定義にNPMを使う
  61. 61. Many options available for more complicated builds: grunt.js, gulp.js, or broccoli より複雑なビルドの場合、grunt.js, gulp.js, broccoliのようなツールを使う
  62. 62. Thousands of plugins for all common build tasks プラグインが何千もある
  63. 63. Learn Develop Test Secure Build The framework scorecard Deploy Debug Scale Maintain Share 10 7 8 10 10 10 6 8 10
  64. 64. Learn Develop Test Secure Build The framework scorecard Deploy Debug Scale Maintain Share 10 7 8 10 10 10 6 8 10
  65. 65. Play uses SBT as the build system. SBT is an interactive build system. Play は SBT という対話的ビルドツールを利用
  66. 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" % "10.4.1.3" ) ) 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. 67. Dependencies are managed using Ivy: familiar, but slow. Ivyで依存性を管理する。使い慣れてるけど、実行性能は遅め
  68. 68. Play uses sbt-web to build static content: few plugins; depends on Rhino (slow) or node.js (!). Playは静的コンテンツのビルドにsbt-webを利用する。プラグインが少ない
  69. 69. Learn Develop Test Secure Build The framework scorecard Deploy Debug Scale Maintain Share 10 7 8 10 10 10 6 8 10 7
  70. 70. Learn Develop Test Secure Build The framework scorecard Deploy Debug Scale Maintain Share 10 7 8 10 10 10 6 8 10 7
  71. 71. Many node-friendly hosting options: Heroku, Joyent, Azure, OpenShift, Nodejitsu Node.jsをサポートするホスティング
  72. 72. Monitoring: New Relic, Nodetime, AppDynamics, node-monitor
  73. 73. 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); } Use cluster to run one node instance per CPU cluster を使ってコア毎にインスタンスを稼働
  74. 74. Use forever, monit, or Domain to handle crashes. クラッシュ対処
  75. 75. { "dbConfig": { "host": "localhost", "port": 5984, "dbName": "customers" } } config/default.json var config = require('config'); var host = config.get('dbConfig.host'); server.js Configuration: node-config or nconf
  76. 76. 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 instNaondcee instNaondcee instNaondcee instNaondcee instance Node instNaondcee instNaondcee instNaondcee instance Node instNaondcee instNaondcee instNaondcee instance ロードバランサー、静的コンテンツ、SSL Termination
  77. 77. Learn Develop Test Secure Build The framework scorecard Deploy Debug Scale Maintain Share 10 7 8 10 10 10 6 8 10 7 8
  78. 78. Learn Develop Test Secure Build The framework scorecard Deploy Debug Scale Maintain Share 10 7 8 10 10 10 6 8 10 7 8
  79. 79. A few Play-friendly hosting options: Heroku, playframework-cloud, CloudBees Playをサポートするホスティング
  80. 80. Monitoring: New Relic, metrics-play
  81. 81. Use the SBT Native Packager to package the app as tgz, deb, RPM, etc. Appをネイティブパッケージとして包装できる
  82. 82. dbConfig = { host: "localhost", port: 5984, dbName: "customers" } conf/application.conf val host = Play.current.configuration.getString("dbConfig.host") app/controllers/Application.scala Configuration: Play comes with Typesafe Config
  83. 83. 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
  84. 84. Learn Develop Test Secure Build The framework scorecard Deploy Debug Scale Maintain Share 10 7 8 10 10 10 6 8 10 7 8 7
  85. 85. Learn Develop Test Secure Build The framework scorecard Deploy Debug Scale Maintain Share 10 7 8 10 10 10 6 8 10 7 8 7
  86. 86. Node.js: use IntelliJ or node-inspector to debug Node.js:IntelliJでデバッグできる
  87. 87. Use DTrace, TraceGL, node-stackviz, and node-profiler to debug perf issues 性能問題のデバッグ
  88. 88. var winston = require("winston"); winston.info("CHILL WINSTON! ... I put it in the logs."); Use winston, log4js, or bunyan for logging
  89. 89. Learn Develop Test Secure Build The framework scorecard Deploy Debug Scale Maintain Share 10 7 8 10 10 10 6 8 10 7 8 7 10
  90. 90. Learn Develop Test Secure Build The framework scorecard Deploy Debug Scale Maintain Share 10 7 8 10 10 10 6 8 10 7 8 7 10
  91. 91. Play runs on the JVM, so you can use your favorite IDE to debug: IntelliJ, Eclipse, NetBeans Play:好きなIDEを使える
  92. 92. In dev, Play shows errors right in the browser 開発モードでエラーがブラウザで表示される
  93. 93. Use YourKit, VisualVM, BTrace, and jmap to debug perf issues
  94. 94. Use logback, slf4j, or log4j for logging
  95. 95. Learn Develop Test Secure Build The framework scorecard Deploy Debug Scale Maintain Share 10 7 8 10 10 10 6 8 10 7 8 7 10 10
  96. 96. Learn Develop Test Secure Build The framework scorecard Deploy Debug Scale Maintain Share 10 7 8 10 10 10 6 8 10 7 8 7 10 10
  97. 97. Part 1: scaling for lots of traffic 大量のトラフィックのためのスケーリング
  98. 98. TechEmpower benchmarks. Warning: microbenchmarks are not a substitute for real world perf testing!
  99. 99. JSON serialization
  100. 100. Single query (Note: JDBC is blocking!)
  101. 101. Multiple queries (Note: JDBC is blocking!)
  102. 102. 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 LinkedIn experience #1: Play and Node.js are very fast in a service oriented architecture with NIO. LinkedInの感想:Node.jsもPlayもとても速い
  103. 103. // 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!"); }); LinkedIn experience #2: Play is ok with blocking I/O & CPU/memory bound use cases. Node.js is not. 同期I/O、高メモリ使用率と高CPU使用率の場合、Node.jsの性能が落ちる
  104. 104. Part 2: scaling for large teams and projects 大きいチーム・プロジェクトのためのスケーリング
  105. 105. Node.js: best for small projects, short projects, small teams. Node.js:小さいプロジェクト、短いプロジェクト、小さいチームにいい
  106. 106. Play: best for longer projects. Slower ramp up, but scales well with team & project size. Play:より大きいプロジェクトにスケールできる
  107. 107. For comparison: Spring MVC
  108. 108. Learn Develop Test Secure Build The framework scorecard Deploy Debug Scale Maintain Share 10 7 8 10 10 10 6 8 10 7 8 7 10 10 10 10
  109. 109. Learn Develop Test Secure Build The framework scorecard Deploy Debug Scale Maintain Share 10 7 8 10 10 10 6 8 10 7 8 7 10 10 10 10
  110. 110. Maintenance: the good parts メンテナンス:「良いパーツ」
  111. 111. Functional programming: first class functions, closures, underscore.js 関数型プログラミング
  112. 112. JavaScript is ubiquitous... JSは至る所にある
  113. 113. ...Which means you can share developers, practices, and even code: rendr, derby, meteor そのため、デベロッパー、情報、コードは入手しやすい
  114. 114. Node core is stable and mature. Bugs, regressions, and backwards incompatibility are rare. 安定したコア。バグや後方互換性の問題は比較的少ない
  115. 115. Maintenance: the bad parts メンテナンス:「悪いパーツ」
  116. 116. '' == '0' // false 0 == '' // true 0 == '0' // true false == 'false' // false false == '0' // true false == undefined // false false == null // false null == undefined // true ' trn ' == 0 // true Bad Parts
  117. 117. // 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
  118. 118. Wat
  119. 119. this keyword
  120. 120. 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 コールバック地獄
  121. 121. Many NPM packages are NOT stable or mature. Incompatibility + bugs + dynamic typing = pain. NPMに不安定なパッケージが多い。非互換性 + バグ + 動的型付け = 苦痛
  122. 122. Learn Develop Test Secure Build The framework scorecard Deploy Debug Scale Maintain Share 10 7 8 10 10 10 6 8 10 7 8 7 10 10 10 10 3
  123. 123. Learn Develop Test Secure Build The framework scorecard Deploy Debug Scale Maintain Share 10 7 8 10 10 10 6 8 10 7 8 7 10 10 10 10 3
  124. 124. Maintenance: the good parts
  125. 125. 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)) Functional programming } }
  126. 126. Powerful type system
  127. 127. 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) } } Very expressive: case classes, pattern matching, lazy, option, implicits 表現力が高い
  128. 128. Runs on the JVM; interop with Java.
  129. 129. Concurrency & streaming tools: Futures, Akka, STM, threads, Scala.rx, Async/Await, Iteratees
  130. 130. 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 } } No callback hell!
  131. 131. Good IDE support
  132. 132. Maintenance: the bad parts
  133. 133. Slow compiler コンパイラ遅い
  134. 134. Fortunately, Play/SBT support incremental compilation and hot reload! Play/sbt はインクリメンタルコンパイラと hot reloading があるから大丈夫!
  135. 135. Complexity
  136. 136. More complexity
  137. 137. Play is stable, but not mature: backwards incompatible API changes every release. Play は安定だがまだ成長期。APIはよく変わる
  138. 138. Even worse: Scala is not binary compatible between releases! Scala はリリース間でバイナリ互換性を持たない!
  139. 139. Backwards incompatibility = pain. … Static typing makes it a little more manageable. バイナリ互換性が無いのは辛いけど、静的な型によって少しは緩和される
  140. 140. Learn Develop Test Secure Build The framework scorecard Deploy Debug Scale Maintain Share 10 7 8 10 10 10 6 8 10 7 8 7 10 10 10 10 3 8
  141. 141. Learn Develop Test Secure Build The framework scorecard Deploy Debug Scale Maintain Share 10 7 8 10 10 10 6 8 10 7 8 7 10 10 10 10 3 8
  142. 142. 544 Contributors 351 2,376 Watchers 576 31,332 Stars 5,077 6,970 Forks 1,872 3,066 PR’s 2,201 Github activity as of 08/10/14
  143. 143. StackOverflow 10,698 53,555 Questions Google Group 14,199 Members 11,577 Google Group ~400 Posts/Month ~1,100 StackOverflow, mailing list activity as of 08/12/14
  144. 144. 4 langpop.com 18 10 TIOBE 39 5 CodeEval 12 7 IEEE Spectrum 17 1 RedMonk 13 12 Lang-Index 26 Language Popularity as of 08/12/14 人気ランキング
  145. 145. 88,000 packages in NPM ~80 Play Modules
  146. 146. 88,000 packages in NPM 83,000 artifacts in Maven
  147. 147. Joyent offers commercial support for Node.js Typesafe offers commercial support for Play 有償サポート
  148. 148. Node.js in production
  149. 149. Play in production
  150. 150. 1,172 LinkedIn 49 3,605 Indeed 179 214 CareerBuilder 16 Open jobs as of 08/13/14 採用募集数
  151. 151. 82,698 LinkedIn 9,037 2,267 Indeed 206 447 CareerBuilder 30 Candidates as of 08/13/14 採用候補者数
  152. 152. Learn Develop Test Secure Build The framework scorecard Deploy Debug Scale Maintain Share 10 7 8 10 10 10 6 8 10 7 8 7 10 10 10 10 3 8 10 7
  153. 153. Learn Develop Test Secure Build The framework scorecard Deploy Debug Scale Maintain Share 10 7 8 10 10 10 6 8 10 7 8 7 10 10 10 10 3 8 10 7
  154. 154. Final score 85 84
  155. 155. Final score 85 84
  156. 156. 山田くん、これ全員の座布団全部持って行きなさい!
  157. 157. Both frameworks are great. Decide based on strengths/weakness, not my arbitrary score! 結論:どちらもすごい!
  158. 158. Use node.js if: 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 向き: 小チーム小アプリ、JavaScript ニンジャ
  159. 159. Don’t use node.js if: 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 不向き: 自動テスト書かない人、大チーム、高CPU か 高RAM
  160. 160. Use Play if: 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 向き: JVM ユーザ、型安全性、関数型が好き、大チーム
  161. 161. Don’t use Play if: 1. You don’t have time to master Play, Scala, and SBT 2. You hate functional programming or static typing 不向き: Play/Scala/sbt を勉強してる時間が無い、型安全性、関数型が嫌い
  162. 162. Questions?

×