Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Scala Fukuoka Play 25 2016

Scala Fukuoka Play 25 2016

Play Framework 2.5 でつくる Web アプリケーション

tsuyoshi yoshizawa

May 28, 2016
Tweet

More Decks by tsuyoshi yoshizawa

Other Decks in Technology

Transcript

  1. Play + Scala ܦݧྺ • Java Λத৺ʹडୗҊ݅ • ओʹ Seasar2

    ϑϨʔϜϫʔΫ • Play 2.0 ͔Βຊ֨తʹ Scala Λ৮Δ • ͍͍ͩͨ 4 ೥͙Β͍ • αʔϏεΛͭ͘Δͱ͖ʹબఆ • ຊӡ༻ظؒ͸ 2 ೥
  2. Play + Scala ΛબΜͩཧ༝ • Java 8 ͸·ͩͳ͘ Scala ʹڵຯ

    • ίϨΫγϣϯ API ͕ศརͩͬͨ • Option ͕ॳΊ͔Β૊Έࠐ·Ε͍ͯͨ • ؆ܿͳίʔυʹͰ͖Δ • Java ࢿ࢈ʢϥΠϒϥϦʣ͕ར༻Ͱ͖Δ • ॻ͍ͯΈָ͔ͯͬͨ͠
  3. Play Framework makes it easy to build web applications with

    Java & Scala. Play is based on a lightweight, stateless, web-friendly architecture.
  4. RESTful GET /users/:id controllers.UserController.find(id: Long) class 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 UserController.scala
  5. εςʔτϨε • ηογϣϯ৘ใ͸ ΫϥΠΞϯταΠυ (Cookie) ʹจࣈྻΛอ࣋ • ΩʔΛݩʹ DB/Ehcache/Redis ͳͲʹ

    อଘ͢Δ • HMAC-SHA1 ʹΑΔॺ໊ • play.crypto.secret ҉߸伴ͷΩʔ (application.conf)
  6. ϦόʔεϧʔςΟϯά GET /users/:id controllers.UserController.find(id: Long) POST /users/create controllers.UserController.create class UserController

    extends Controller { def create = Action { implicit request => // ࡞੒ॲཧ val user = ??? Redirect(routes.UserController.find(user.id)) } } • ίϯύΠϧνΣοΫʹΑΔ҆৺ײ • ύϥϝʔλʔɺ URL มߋ΁ͷࣗಈ௥ਵ <a href=“@routes.UserController.find(user.id)”>@user.name</a> view
  7. ςϯϓϨʔτΤϯδϯ (twirl) @(customer: Customer, orders: List[Order]) <h1>Welcome @customer.name!</h1> <ul> @for(order

    <- orders) { <li>@order.title</li> } </ul> • ίϯύΠϧνΣοΫʹΑΔ҆৺ײ • Scala ه๏Ͱهड़ view
  8. HTTP ϦΫΤετϋϯυϦϯά case class UserData(name: String, age: Int) val userForm

    = Form( mapping( "name" -> nonEmptyText, "age" -> number(min = 0, max = 100) )(UserData.apply)(UserData.unapply) ) • ύϥϝʔλʔͷܕ߹Θͤ΋ίϯύΠϧνΣοΫ • content-type ʹΑΔϋϯυϦϯάରԠ • application/x-www-form-urlencoded • application/json
  9. Play ෇ଐϥΠϒϥϦ • Web ΞϓϦΛ࡞੒͢Δ্Ͱ࠷௿ݶͷ ϥΠϒϥϦ͕෇ଐ͍ͯ͠Δ • Play JSON •

    Play WS • HTTP client • OAuth client • Play Filters (CSRF, CORS …)
  10. Dependency Injection • JSR 330 ඪ४࢓༷ʹ४ڌ • ίϯετϥΫλΠϯδΣΫγϣϯਪ঑ • Play

    2.4 ͔Βಋೖ import javax.inject.Inject import play.api.libs.ws._ class MyComponent @Inject()(wsClient: WSClient) { def request(url: String) = { wsClient.url(url).get() … } }
  11. ࣮૷੾Γସ͑ྫ • trait (interface) ʹΑΔ։ൃ؀ڥ/ຊ൪؀ ڥͷ࣮૷੾Γସ͑΋ίʔυͰදݱ class MyModule(environment: Environment, configuration:

    Configuration) extends AbstractModule { override def configure() = { configuration.getString("storage.type") match { case Some(t) if t == "local" => bind(classOf[StorageService]).to(classOf[LocalStorageService]) case Some(t) if t == "s3" => bind(classOf[StorageService]).to(classOf[S3StorageService]) case t => sys.error(s"The storage type is not supported: $t") } } }
  12. ࠃࡍԽରԠ (i18n) • ϝοηʔδϦιʔε͸ conf/messages ϑΝΠϧʹ key=value ܗࣜͰهड़ • ϩέʔϧΛ֦ுࢠʹ෇Ճͯ͠ෳ਺ݴޠ

    ରԠ • conf/messages.ja-JP • conf/messages.fr play.i18n.langs=[“en-US”,"ja-JP", “fr”]
  13. ࠃࡍԽରԠྫ import javax.inject.Inject import play.api.i18n.I18nSupport class UserController @Inject()(val messagesApi: MessagesApi)

    extends Controller with I18nSupport { def hello = Action { implicit request => Ok(Json.obj( “text” -> Messages(“hello”) )) } } hello=Hello Scala! hello=͜Μʹͪ͸ Scala! messages.ja-JP messages
  14. ࠃࡍԽରԠϫϯϙΠϯτ • ݴޠͷద༻͸ΫϥΠΞϯτ৘ใ͔Β 1. Cookie (PLAY_LANG) 2. AcceptLanguage (HTTP Header)

    • MessagesApi#setLang Ͱ Cookie ʹ൓ө Lang(Locale.JAPAN) Lang.get(“ja-JP”).getOrElse(Lang.defaultLang)
  15. Typesafe config db { default { driver = org.postgresql.Driver }

    } • Java ϥΠϒϥϦ Scala ϥούʔ • HOCON ܗࣜ (JSON Superset) • ઃఆϑΝΠϧΛ include Ͱ͖Δʢ্ॻ͖ʣ • application.conf -> prod.conf -> beta.conf
  16. ͕͍͍͜͜Α Play ·ͱΊ • RESTful ϑϨʔϜϫʔΫ • εέʔϧΞ΢τ͠΍͍͢ • ա৒ͳ·Ͱͷܕ҆શ

    • Ξϊςʔγϣϯ΋΄΅ͳ͘ॻ͍ͯ͋Δ ͱ͓Γʹಈ҆͘৺ײ • ࢼ͠ͳ͕Β։ൃΛਐΊ͍͚ͯΔ
  17. Scala ඇಉظॲཧ import scala.concurrent.ExecutionContext.Implicits.global Future { // Some blocking or

    expensive code here } • Future Λ࢖͏͜ͱͰɺॲཧΛඇಉظԽ ͢Δ͜ͱ͕Ͱ͖Δ • CPU ίΞ਺෼ಉ࣌ʹॲཧ • Java8 CompletableFuture తͳ΋ͷ
  18. Play Scala ඇಉظॲཧ import play.api.libs.concurrent.Execution.Implicits._ • Future Λ࢖͏ • import

    ઌΛมߋ͢Δ͜ͱ • Play ͸σϑΥϧτ 24 ݸ·ͰͷϦΫΤε τΛฒྻͰड͚औΔ • Thread Pool ͕ރׇ͢Δͱ৽نϦΫΤε τ͕଴ͪঢ়ଶʹͳΔ
  19. σϑΥϧτεϨουϓʔϧௐ੔ akka { actor { default-dispatcher = { fork-join-executor {

    parallelism-min = 100 parallelism-max = 100 } } } } • ϦϦʔεલʹඞͣνϡʔχϯά • DB ࠷େ઀ଓ਺Λ֬ೝ
  20. ผεϨουϓʔϧ࡞੒ contexts { http { fork-join-executor { parallelism-factor = 20.0

    parallelism-max = 200 } } } val executionContext = akkaSystem.dispatchers.lookup(“contexts.http”) Future { // Some blocking or expensive code here }(executionContext)
  21. • ద੾ʹεϨουϓʔϧΛఆٛ͠ύϑΥʔ Ϛϯενϡʔχϯά • DB ࠷େ઀ଓ਺΋֬ೝ • εϨουΛա৴͗ͣ͢͠ SQS ͳͲͷ

    ϝοηʔδΩϡʔ΋ߟྀ Play εϨουϓʔϧ·ͱΊ https://www.playframework.com/documentation/ 2.5.x/ThreadPools
  22. ORM • Slick • Lightbender ࣾʹΑΔ ORM • Slick 3.0

    ͔ΒඇಉظΞΫηεΛਪ঑ • ScalikeJDBC • ૉ௚ʹ͔͚ͯେ͖ͳϋϚϦͳ͠ • جຊతʹ SQL Ͱهड़͢Δ։ൃʹ • νϡʔχϯά͍͔ͨ͠Β
  23. ϦόʔεϓϩΩγ໰୊ play { http { forwarded.trustedProxies=[“10.0.0.0/8”, "::1", “127.0.0.1"] } }

    • Nginx ͳͲϦόʔεϓϩΩγΛஔ͍ͯ IP ΞυϨεΛऔಘ͍ͨ͠ • ৴པ͢Δ Private ωοτϫʔΫΛࢦఆ
  24. Play ৘ใपΓ • Stackoverflow ͕ୈೋͷυΩϡϝϯτ • ೔ຊޠपΓ • Blog ౳͸ݹ͘ͳΓ͕ͪ

    • ༗ࢤͷํʑʹΑΔຊՈ຋༁ • https://gitter.im/scalajp/public • @scalajp_gitter (twitter)
  25. ίϯύΠϧ଎౓ྫ 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 ͕ࠩ෼ίϯύΠϧͯ͘͠ ΕΔ
  26. ίϯύΠϧ଎౓վળ sources in (Compile, doc) := Nil, publishArtifact in (Compile,

    packageDoc) := false build.sbt • υΩϡϝϯτϑΝΠϧੜ੒͠ͳ͍ • ϑΝΠϧमਖ਼ޙʹࣗಈίϯύΠϧ $ sbt ~run # activator ~run
  27. ޓ׵ੑ໰୊ • Play όʔδϣϯޓ׵ੑ໰୊ • ։ൃ଎౓͕଎͍ʢϝϦοτͰ΋͋Δʣ • Ҡߦظؒ͸͘ΕΔ͕ഁյత • Scala

    όʔδϣϯޓ׵ੑ໰୊ • ϚΠφʔόʔδϣϯ͝ͱʹόΠφϦޓ ׵ੑ͕ͳ͍ • ϥΠϒϥϦʹ PR ૹͬͨΓ fork ͨ͠Γ
  28. Build front-end with sbt • ։ൃ࣌͸ sbt ʹλεΫΛ௥Ճͯࣗ͠ಈ Ͱ gulp

    (npm) Λ࣮ߦ • https://www.playframework.com/ documentation/2.5.x/SBTCookbook
  29. Play Framework ·ͱΊ • Lightbend ࣾʹΑΔ Scala Web Framework ͷσϑΝΫτ

    • τϨϯυΛऔΓೖΕͯ։ൃ͕׆ൃ • গͳ͘ͱ΋ ̐ ೥͸ܧଓ͓ͯ͠Γɺ 2.6/3.0 ʹ޲͚ͯ։ൃத