Share
Embed
Java ラブなヌーラボにおける Scala + Playframework 体験記
Presentation slides at https://jissenscala.doorkeeper.jp/events/19660
Transcript
35 slides
-
ࣗݾհ • Tsuyoshi Yoshizawa (@ussy00) • גࣜձࣾψʔϥϘ • 2009 -
2012 • डୗ։ൃ / Backlog / Cacoo • 2013 - • Typetalk (project leader) -
ψʔϥϘͷྺ࢙ 2004 2006 2010 2014 Nulab Backlog Cacoo Backlog API
v2 Java Java / Seasar2 Java / Seasar2 Scala / Play2 Typetalk Nulab Account Java8 / Spring Nulab Status Go -
Seasar2 ͱͷܾผ • 2012 Typetalk ϓϩτλΠϓΛझຯͰ։࢝ • Seasar2 ϝϯςφϯεϞʔυ
• RESTful/Web API/WebSocket ਐԽࢭ·Βͳ ͍ • ଞͷϑϨʔϜϫʔΫΛ୳͢͜ͱʹ -
ϑϨʔϜϫʔΫ୳ࡧ • Ruby on Rails • ੩తܕ͚ʹ׳Ε͖ͬͯ͠·͍ͬͯͨ • ࣗͰϝϯς͠ଓ͚ΒΕΔࣗ৴͕ͳ͔ͬͨ •
Spring Framework (Spring MVC / JAX-RS) • Seasar2 Λஔ͖͑Δʹ࠷దͰ͕͋ͬͨɺΓ ͳ͕͋ͬͨ͞ -
• Playframework 1 ͷ͖উख͍ͬͯͨ͞ • Scala ΛϝΠϯͱͨ͠ Web ϑϨʔϜϫʔΫ •
Playframework 2.0 ਖ਼ࣜϦϦʔεલ • ৽نϓϩδΣΫτͰࢼߦࡨޡܹ͘͢͠త -
RESTful GET /users/:id controllers.UserController.find(id: Long) object UserController extends Controller {
def find(id: Long) = Action { implicit request => User.findById(id).map { user => Ok(Json.obj( “id” -‐> user.id, “name” -‐> user.name )) }.getOrElse { NotFound(Json.obj( “message” -‐> “User not found” )) } } } routes controller -
Hot Reloading • ։ൃ͕͍͢͠ • LL ͷੈքͰͨΓલ • dev ϞʔυͰແઃఆͰಈ࡞͢Δ
• Seasar2 ಉ༷ ClassLoader Λࠩ͠ସ࣮͑ͯݱ • play.runsupport.Reloader (2.4.x) -
Type-safe View • HTML Λฦͯ͠ JSON Λऔಘ͢Δ͚࣌ͩΕͲ • ܕͷߏΛมߋͨ͠ΒΤϥʔʹͳΔ҆৺ײ •
ϝʔϧςϯϓϨʔτʹ༻Մ • HTML ίʔμʔʹͱͬͯਏ͍ @(account: Account) <span class="name">@account.name</span> -
Type-safe Reverse Routing ϝιουͷγάωνϟ͕ มΘΕίϯύΠϧΤϥʔ GET /users/:id controllers.UserController.find(id: Long) <a
href=“@routes.UserController.find(user.id)”>@user.name</a> template routes val url = routes.UserController.find(user.id) Scala -
Database Migration • ϑΟʔνϟʔϒϥϯν։ൃͱ૬ੑ͕Α͍ • ϨϏϡʔΛؾܰʹߦ͑Δ • ϑΝΠϧ໊࿈൪Ͱཧ (n.sql) •
Ϛʔδ͢Δͱ͖ʹίϯϑϦΫτΛىͤ͜Δ -
ޓੑ • มߋʹޙํޓੑ͕ͳ͘ͳΔ͜ͱ͕͋Δ • Ϧʔυίϛολʔ͕ James Roper ͞Μ (Typesafe) ʹ
ͳͬͯྑ͍ํʹ͔͍ͬͯΔ • ৽͍͠όʔδϣϯ͕ग़ͨΒɺͱʹ͔͘ਵ • ࣗͨͪͰΛ֬อͰ͖Δ͔ΒɺΓ͔ͬͨ͢ -
Build front-end • Playframework 2.3 SBT Web • ඇެࣜ Plugin
ͷΞοϓάϨʔυͷอোੑ • Grunt/Gulp ʹൺΔͱຬ͍͔ͳ͔ͬͨ • ΤίγεςϜʹΔ͘ Gulp ʹશ໘Ҡߦ -
Build front-end with SBT • PlayRunHook Λ࣮͢Δ͜ͱͰɺ SBT ͱ࿈ܞ͞ ͤͯɺىಈ࣌ʹ
grunt/gulp Λ࣮ߦ • http://hakobe932.hatenablog.com/entry/ 2014/04/02/220457 • https://www.playframework.com/ documentation/2.4.x/SBTCookbook -
Scala ͷڵຯ Immutable Trait Pattern match Lazy evaluation Option Collection
API JVM Future Lambda -
Option def findLang(lang: String): Lang = supportLangs.find { l
=> l.code == lang }.getOrElse(english) findLang(“ja-‐JP”) • NullPointerException ͷ࣮ߦ࣌ྫ֎͕ൃੜ͠ͳ͍ • Scala ݩ͔Β Option ͕͋ΔઃܭͳͨΊɺ֤ϥ ΠϒϥϦ͕ Option Λฦͯ͘͠ΕΔ҆৺ײ -
case class case class User(id: Long, name: String, isAdmin: Boolean)
val newUser = User(1L, “yoshizawa”, false) val updatedUser = newUser.copy(name = “tsuyoshizawa”) • σϑΥϧτͰಡΈऔΓઐ༻ϓϩύςΟ͕༩ • equals/hashCode/toString/copy … ϝιουΛੜ • copy ͰݩͷΦϒδΣΫτΛഁյͤͣʹίϐʔ • pattern match ద༻ՄೳʹͳΔ -
pattern match • Option ͷ matching Ͱཏ͞Εͯͳ͍߹ܯࠂ • ΦϒδΣΫτΛղͯ͠ΛऔΓग़͢͜ͱ͕Ͱ͖Δ findById(id)
match { case Some(user) if user.isAdmin => “administrator” case Some(user) => “normal user” // case _ => “guest user” warning! } val r = “""(\d{4})-‐(\d{2})-‐(\d{2})""".r “2015-‐02-‐22” match { case r(year, month, day) => something(year, month, day) case _ => throw new Exception(“format exception”) } if Ψʔυઅ͕͋Δ ߹ବ -
࣮ߦ࣌ྫ֎͕ൃੜ͢Δέʔε • Java • ϓϩάϥϚʔ͕ྫ֎ͳ (null) Λฦ͞ΕΔ͜ͱΛ ༧Ͱ͖ͳ͔ͬͨ • Scala
• Option#get, List#head Λҙਤతʹݺͼग़͢ Scala Ͱهड़͢Δ͜ͱͰέΞϨεϛεΛݮΒͤΒΕΔ -
Self annotation • API ϑΝʔετͰ։ൃ • ॲཧڞ௨Խ͠ೝূΛ Web ͱ API
Ͱ͚͍ͨ • ೝূॲཧΛ trait ʹ࣮͠ɺॊೈʹΈࠐΈ͕Ͱ͖ͨ trait MessageController extends Controller { self: Auth => // API methods } object MessageWebController extends MessageController with WebAuth object MessageApiController extends MessageController with APIAuth ೝূํࣜΛޙ͔Βܾఆ -
Scala ϥΠϒϥϦͷधཁ • Typetalk / Backlog API v2 API ެ։
• ࣮࣌ʹ Scala ͚ͷ OAuth2 Provider ϥΠϒϥϦ ͕ͳ͔ͬͨ • Github ʹެ։ • https://github.com/nulab/scala-oauth2-provider -
OSS ʹͯ͠Έͯ • ӳޠͰެ։ͯ͠Α͔ͬͨ • ϑΟʔυόοΫΛ͘ΕΔਓඇӳޠݍ • ៉ྷͳӳޠͰ͋Δඞཁͳ͍ • ڹʢϑΟʔυόοΫʣ͕͋Δͱخ͍͠
• Awesome Scala ʹܝࡌͯ͠Β͑ͨ -
ӡ༻ • munin / Mackerel Λͬͯࢹ • Java ͷӡ༻ࢿ࢈Λͦͷ··ར༻͢Δ͜ͱ͕Ͱ͖ͨ https://speakerdeck.com/nulabinc/
java-8-falsehipumonitaringu Java 8 ͷώʔϓϞχλϦϯά -
όΠφϦޓੑ • ϝδϟʔόʔδϣϯ͕มΘΔͱόΠφϦޓੑ͕ ͳ͘ͳΔ • ಛఆϥΠϒϥϦʹҾ͖ͣΒΕ Scala ͷϝδϟʔ όʔδϣϯΞοϓ͕؆୯Ͱͳ͍߹͕͋Δ (2.9
- > 2.10 -> 2.11 ͱରԠ͖ͯͨ͠ʣ • ར༻͍ͯ͠ΔϥΠϒϥϦʹ PR Λग़͍ͯ͘͠ • Ұ࣌తʹΠϯϋεϦϙδτϦʹ্͛ͨΓ -
ίϯύΠϧ • ผϓϩδΣΫτɺαϒϓϩδΣΫτԽ • Α͍εϖοΫͷ PC Λߪೖ͠ʢͯΒ͍ʣ·͠ΐ͏ • ScalaDoc ͕͍Βͳ͍ϓϩδΣΫτͰ͋Ε
sources in (Compile, doc) := Nil publishArtifact in (Compile, packageDoc) := false build.sbt -
clean compile (ࣾൺ) 0 50 100 67s 90s MBA 11-inch
Mid 2012 (2.0 GHz intel Core i7) MBP Retina 15-inch Early 2013 (2.7 GHz Intel Core i7) ։ൃ࣌ຖճΫϦʔϯίϯ ύΠϧ͢ΔΘ͚Ͱͳ͍ SBT ͕ࠩίϯύΠϧͯ͠ ͘ΕΔ -
Scala ͬͯͦ͠͏ • ࣮ϓϩδΣΫτൃ࣌ʹ Scala ະܦݧϝϯόʔ ͕ࢀՃ • better Java
Ͱ։࢝ • Scala ͷΑ͍ػೳͱෳࡶ͞ͷόϥϯεΛऔΔ • ίʔυϨϏϡʔͰࢦఠ͢Δ • ྑॻΛखʹऔΔ -
·ͱΊ • Playframework + Scala ʹΑͬͯҎલΑΓΑ͍։ൃ ڥ͕खʹೖͬͨʢಛผͳઃఆͳ͠ʹʣ • Java ΑΓݎ࿚ͳϓϩάϥϛϯά͕Մೳ
• Scala ʹܞΘͬͨ։ൃऀ͕ͭ͘Δ৽͍͠ΞϓϦ ʢπʔϧʣɺ Scala ͕બΕͯΔ • ։ൃνʔϜɺҊ݅ΛݟۃΊͯಋೖͰ͖ΕΑ͍