Slide 1

Slide 1 text

Scala + Playframework ମݧه Java ϥϒͳψʔϥϘʹ͓͚Δ

Slide 2

Slide 2 text

No content

Slide 3

Slide 3 text

ࣗݾ঺հ • Tsuyoshi Yoshizawa (@ussy00) • גࣜձࣾψʔϥϘ • 2009 - 2012 • डୗ։ൃ / Backlog / Cacoo • 2013 - • Typetalk (project leader)

Slide 4

Slide 4 text

ψʔϥϘͷྺ࢙ 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

Slide 5

Slide 5 text

Seasar2 ͱͷܾผ • 2012 ೥ Typetalk ϓϩτλΠϓΛझຯͰ։࢝ • Seasar2 ϝϯςφϯεϞʔυ • RESTful/Web API/WebSocket ਐԽ͸ࢭ·Βͳ ͍ • ଞͷϑϨʔϜϫʔΫΛ୳͢͜ͱʹ

Slide 6

Slide 6 text

ϑϨʔϜϫʔΫ୳ࡧ • Ruby on Rails • ੩తܕ෇͚ʹ׳Ε͖ͬͯ͠·͍ͬͯͨ • ࣗ෼Ͱϝϯς͠ଓ͚ΒΕΔࣗ৴͕ͳ͔ͬͨ • Spring Framework (Spring MVC / JAX-RS) • Seasar2 Λஔ͖׵͑Δʹ࠷దͰ͸͕͋ͬͨɺ෺଍Γ ͳ͕͋ͬͨ͞

Slide 7

Slide 7 text

• Playframework 1 ͷ޷͖উख͞͸஌͍ͬͯͨ • Scala ΛϝΠϯͱͨ͠ Web ϑϨʔϜϫʔΫ • Playframework 2.0 ਖ਼ࣜϦϦʔε௚લ • ৽نϓϩδΣΫτͰࢼߦࡨޡ͠΍ܹࢗ͘͢త

Slide 8

Slide 8 text

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

Slide 9

Slide 9 text

Hot Reloading • ։ൃ͕͠΍͍͢ • LL ͷੈքͰ͸౰ͨΓલ • dev ϞʔυͰແઃఆͰಈ࡞͢Δ • Seasar2 ಉ༷ ClassLoader Λࠩ͠ସ࣮͑ͯݱ • play.runsupport.Reloader (2.4.x)

Slide 10

Slide 10 text

Type-safe View • HTML Λฦͯ͠ JSON Λऔಘ͢Δ࣌୅͚ͩΕͲ΋ • ܕͷߏ଄Λมߋͨ͠ΒΤϥʔʹͳΔ҆৺ײ • ϝʔϧςϯϓϨʔτʹ΋࢖༻Մ • HTML ίʔμʔʹͱͬͯ͸ਏ͍ @(account:  Account)   @account.name

Slide 11

Slide 11 text

Type-safe Reverse Routing ϝιουͷγάωνϟ͕ มΘΕ͹ίϯύΠϧΤϥʔ GET  /users/:id  controllers.UserController.find(id:  Long) @user.name template routes val  url  =  routes.UserController.find(user.id) Scala

Slide 12

Slide 12 text

Database Migration • ΞοϓάϨʔυ/μ΢ϯάϨʔυΛαϙʔτ • ίϚϯυΛೖྗ͢Δඞཁ͸ͳ͍ • ϖʔδΛϦϩʔυ͢Δ͚ͩ • ʮϚΠάϨʔγϣϯ࣮ߦ͍ͯͩ͘͠͞ʯ໰୊ճආ

Slide 13

Slide 13 text

Database Migration

Slide 14

Slide 14 text

Database Migration ϒϥϯνʹνΣοΫΞ΢τޙ ΞοϓάϨʔυ SQL ͕૸Δ ϒϥϯνΛ໭ͤ͹ μ΢ϯάϨʔυ SQL ͕૸Δ

Slide 15

Slide 15 text

Database Migration • ϑΟʔνϟʔϒϥϯν։ൃͱ૬ੑ͕Α͍ • ϨϏϡʔΛؾܰʹߦ͑Δ • ϑΝΠϧ໊͸࿈൪Ͱ؅ཧ (n.sql) • Ϛʔδ͢Δͱ͖ʹίϯϑϦΫτΛىͤ͜Δ

Slide 16

Slide 16 text

Playframework ໰୊఺

Slide 17

Slide 17 text

ޓ׵ੑ໰୊ • มߋʹޙํޓ׵ੑ͕ͳ͘ͳΔ͜ͱ͕͋Δ • Ϧʔυίϛολʔ͕ James Roper ͞Μ (Typesafe) ʹ ͳͬͯྑ͍ํ޲ʹ޲͔͍ͬͯΔ • ৽͍͠όʔδϣϯ͕ग़ͨΒɺͱʹ͔͘௥ਵ • ࣗ෼ͨͪͰ޻਺Λ֬อͰ͖Δ͔Βɺ΍Γ΍͔ͬͨ͢

Slide 18

Slide 18 text

Build front-end • Playframework 2.3 SBT Web • ඇެࣜ Plugin ͷΞοϓάϨʔυͷอোੑ • Grunt/Gulp ʹൺ΂Δͱຬ଍͍͔ͳ͔ͬͨ • ΤίγεςϜʹ৐Δ΂͘ Gulp ʹશ໘Ҡߦ

Slide 19

Slide 19 text

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

Slide 20

Slide 20 text

Scala Λ࢖ͬͯΈͯ

Slide 21

Slide 21 text

Scala ΁ͷڵຯ Immutable Trait Pattern match Lazy evaluation Option Collection API JVM Future Lambda

Slide 22

Slide 22 text

Option def  findLang(lang:  String):  Lang  =   supportLangs.find  {  l  =>  l.code  ==  lang  }.getOrElse(english)   findLang(“ja-­‐JP”)   • NullPointerException ͷ࣮ߦ࣌ྫ֎͕ൃੜ͠ͳ͍ • Scala ͸ݩ͔Β Option ͕͋ΔઃܭͳͨΊɺ֤ϥ ΠϒϥϦ͕ Option Λฦͯ͘͠ΕΔ҆৺ײ

Slide 23

Slide 23 text

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 ΁ద༻ՄೳʹͳΔ

Slide 24

Slide 24 text

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 Ψʔυઅ͕͋Δ ৔߹͸ବ໨

Slide 25

Slide 25 text

࣮ߦ࣌ྫ֎͕ൃੜ͢Δέʔε • Java • ϓϩάϥϚʔ͕ྫ֎ͳ஋ (null) Λฦ͞ΕΔ͜ͱΛ ༧૝Ͱ͖ͳ͔ͬͨ • Scala • Option#get, List#head Λҙਤతʹݺͼग़͢ Scala Ͱهड़͢Δ͜ͱͰέΞϨεϛεΛݮΒͤΒΕΔ

Slide 26

Slide 26 text

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 ೝূํࣜΛޙ͔Βܾఆ

Slide 27

Slide 27 text

Scala ϥΠϒϥϦͷधཁ • Typetalk / Backlog API v2 API ެ։ • ࣮૷࣌ʹ Scala ޲͚ͷ OAuth2 Provider ϥΠϒϥϦ ͕ͳ͔ͬͨ • Github ʹެ։ • https://github.com/nulab/scala-oauth2-provider

Slide 28

Slide 28 text

OSS ʹͯ͠Έͯ • ӳޠͰެ։ͯ͠Α͔ͬͨ • ϑΟʔυόοΫΛ͘ΕΔਓ΋ඇӳޠݍ • ៉ྷͳӳޠͰ͋Δඞཁ͸ͳ͍ • ൓ڹʢϑΟʔυόοΫʣ͕͋Δͱخ͍͠ • Awesome Scala ʹ΋ܝࡌͯ͠΋Β͑ͨ

Slide 29

Slide 29 text

ӡ༻ • munin / Mackerel Λ࢖ͬͯ؂ࢹ • Java ͷӡ༻ࢿ࢈Λͦͷ··ར༻͢Δ͜ͱ͕Ͱ͖ͨ https://speakerdeck.com/nulabinc/ java-8-falsehipumonitaringu Java 8 ͷώʔϓϞχλϦϯά

Slide 30

Slide 30 text

Scala ໰୊఺

Slide 31

Slide 31 text

όΠφϦޓ׵ੑ໰୊ • ϝδϟʔόʔδϣϯ͕มΘΔͱόΠφϦޓ׵ੑ͕ ͳ͘ͳΔ • ಛఆϥΠϒϥϦʹҾ͖ͣΒΕ Scala ͷϝδϟʔ όʔδϣϯΞοϓ͕؆୯Ͱͳ͍৔߹͕͋Δ (2.9 - > 2.10 -> 2.11 ͱରԠ͖ͯͨ͠ʣ • ར༻͍ͯ͠ΔϥΠϒϥϦʹ PR Λग़͍ͯ͘͠ • Ұ࣌తʹΠϯϋ΢εϦϙδτϦʹ্͛ͨΓ΋

Slide 32

Slide 32 text

ίϯύΠϧ଎౓໰୊ • ผϓϩδΣΫτɺαϒϓϩδΣΫτԽ • Α͍εϖοΫͷ PC Λߪೖ͠ʢͯ΋Β͍ʣ·͠ΐ͏ • ScalaDoc ͕͍Βͳ͍ϓϩδΣΫτͰ͋Ε͹    sources  in  (Compile,  doc)  :=  Nil      publishArtifact  in  (Compile,  packageDoc)  :=  false build.sbt

Slide 33

Slide 33 text

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 ͕ࠩ෼ίϯύΠϧͯ͠ ͘ΕΔ

Slide 34

Slide 34 text

Scala ͬͯ೉ͦ͠͏ • ࣮ϓϩδΣΫτൃ଍࣌ʹ Scala ະܦݧϝϯόʔ ͕ࢀՃ • better Java Ͱ։࢝ • Scala ͷΑ͍ػೳͱෳࡶ͞ͷόϥϯεΛऔΔ • ίʔυϨϏϡʔͰࢦఠ͢Δ • ྑॻΛखʹऔΔ

Slide 35

Slide 35 text

·ͱΊ • Playframework + Scala ʹΑͬͯҎલΑΓ΋Α͍։ൃ ؀ڥ͕खʹೖͬͨʢಛผͳઃఆͳ͠ʹʣ • Java ΑΓ΋ݎ࿚ͳϓϩάϥϛϯά͕Մೳ • Scala ʹܞΘͬͨ։ൃऀ͕ͭ͘Δ৽͍͠ΞϓϦ ʢπʔϧʣ͸ɺ Scala ͕બ͹ΕͯΔ • ։ൃνʔϜɺҊ݅ΛݟۃΊͯಋೖͰ͖Ε͹Α͍