scala for play

67
for for [email protected] 라 스칼라 코딩단 최정열

Upload: brandon-choi

Post on 17-Jun-2015

1.856 views

Category:

Documents


4 download

TRANSCRIPT

2. Play , . 3. Scala for Play 4. ... ... ... ... 5. ... Quick and Dirty Testablity & TDD able JAVA JVM 6. ... 7. History - Play 1.x 8. History - Play 1.x 9. History - Play 1.x SBTAkkaTemplate 10. History - Play 2 11. ? 12. ! 3 ? 13. 2013 14. Play frameworkSimpleGreat Testing SupportURL RoutingJPA/Ebean Support (Java only)Class ReloadingNIO Server(Netty)Share-NothingAsset CompilerJava & Scala Supporti18nCompile time checkingInstant deply on Heroku, Cloud bees 15. Simple 16. ServletPlay 17. Simple > All in One 18. Simple > Code Restful Routes GET/indexcontrollers.App.indexStraitforward Controllers Action { Request Response } Easy Template @name 19. Simple > Web Spec HTTP/1.1(rfc2616)HTML5 / CSS 20. Simple > Http Result Result.scala def SeeOther(url: String): SimpleResult = Redirect(url, 303) val BadRequest = new Status(400) val NotFound = new Status(404) val InternalServerError = new Status(500) val NoContent = SimpleResult( header = ResponseHeader(204), body = Enumerator.empty, connection = HttpConnection.KeepAlive)} ~ 21. Simple > Test IntegrationTestbrowser.goTo("http://localhost:" + port) browser.pageSource must contain("Hello")UnitTestval home = route(FakeRequest(GET, "/")).get status(home) must equalTo(OK) contentType(home) must beSome.which("text/html") contentAsString(home) must contain ("Hello") 22. Simple > Deploy on Heroku Procfile / !web: target/start -Dhttp.port=${PORT} -DapplyEvolutions.default=true -Ddb.default.url=${DATABASE_URL} -Ddb.default.driver=org.postgresql.DriverDeploy! $ git push heroku master 23. Simple > Deploy on CloudBees 24. Simple > I18n conf/messages error.notfound = Post not found error.required = Mandatory field is empty user.confirmPassword = Confirm Password validation.duplicated = Already exists! validation.required = Required!conf/messages.ko error.notfound = . error.required = . user.confirmPassword = . validation.duplicated = ! validation.required = . 25. Simple > Too Simple . 26. Case Study 27. Play inside 28. Project 1 $ play new myApp 2 $ play 3> runIDE > Idea with-source = true > eclipse with-source=true 29. Structure app assets controllers models views conf application.conf routes public project testLESS CSS, CoffeeScript Application controllers Application business layer Templates Configurations files Main configuration file Routes definition Image, CSS, JavaScript Build, Plugins Setting Unit and Integration Test 30. Play framework Routes Routes ... ... ... ...request requestClientdispatchController 1 2 Controller Controller 1 2 Controllerresponse responseView ViewModel 31. Routes Http methodUriBody (scala code)GET/controllers.App.indexGET/addcontrollers.App.blankPOST/articlecontrollers.App.insertGET/article/$numcontrollers.App.details(num: Long)POST/article/:idcontrollers.App.update(id: Long)POST/article/:id/deletecontrollers.App.delete(id: Long)GET/assets/*filecontrollers.Assets.at(path="/public", file) 32. Routes Http methodUriBody (scala code)GET/controllers.App.indexGET/addcontrollers.App.blankPOST/articlecontrollers.App.insertGET/article/$numcontrollers.App.details(num: Long)POST/article/:idcontrollers.App.update(id: Long)POST/article/:id/deletecontrollers.App.delete(id: Long)GET/assets/*filecontrollers.Assets.at(path="/public", file) 33. Controller POST/article/:idcontrollers.App.detail(id: Long)object App extends Controller { def detail(num: Long) = Action{ OK(Item.find(num)...) } def join = WebSocket{ ... } } 34. Actions def r: Result = Action { Ok("Hello World!") }Action { Ok("Hello World!").withHeaders( CACHE_CONTROL -> "max-age=3600", ETAG -> "xx" )} Action.Async { future.map(i => Ok("Hello World!" + i))} Action (parse.json) { implicit request: => Ok("Request: " + request) } WebSocket.using[String] { request: => val in = Iteratee.foreach[String] val out = Enumerator("Hello!") (in, out) } 35. Requestdef i = Action { implicit req => Ok("Request: [" + req + "]") } 36. Requestdef i = Action { implicit req: [ Ok("Request: [" + req + "]") }] => 37. Requestdef i = Action { implicit req: AnyContent => Ok("Request: [" + req + "]") } 38. Requestdef j = Action(parse.json) { implicit req => Ok("Request: [" + req + "]") } 39. Requestdef j = Action(parse.json) { implicit req: [ Ok("Request: [" + req + "]") }] => 40. Requestdef j = Action(parse.json) { implicit req: JsValue => Ok("Request: [" + req + "]") } 41. Scala for Play . Template implicit keyword Form Option[T] type 42. Scala for Play Tem plate 43. Template . ? . . . 44. Template Header.scala.html @(title: String) @title convert Header.template.scaladef apply(title: String) = { format.raw( "" + title + "" ) } 45. Template@(title: String, articles: List[article]) @import helper._ @main(title){ @articles.map{ article => @article.title }} 46. Template compositionHeadermain (header) (side)(content)sideContent 47. Implicit Parameter 48. Implicitval db: DB = application.getDatabase() def query(str: String)(db: DB): List[User] val users = query("""SELECT * FROM USER""")(db) val posts = query("""SELECT * FROM POST WHERE ...""")(db) val pets = getPost("""SELECT * FROM PET""")(db) 49. Implicitval db: DB = application.getDatabase() def query(str: String)(db: DB): List[User] val users = query("""SELECT * FROM USER""")(db) val posts = query("""SELECT * FROM POST WHERE ...""")(db) val pets = getPost("""SELECT * FROM PET""")(db) 50. Implicitimplicit val db: DB = application.getDatabase() def query(str: String)(implicit db: DB): List[User] val users = query("""SELECT * FROM USER""")(db) val posts = query("""SELECT * FROM POST WHERE ...""")(db) val pets = getPost("""SELECT * FROM PET""")(db) 51. Implicitimplicit val db: DB = application.getDatabase() def query(str: String)(implicit db: DB): List[User] val users = query("""SELECT * FROM USER""") val posts = query("""SELECT * FROM POST WHERE ...""") val pets = getPost("""SELECT * FROM PET""") 52. Implicit import play.api.Play.current def getAll: List[Product] = DB.withConnection { implicit connection => sql().map ( row => Product(row[Long]("id"), row[String]("name") ).toList} 53. Implicit import play.api.Play.current def getAll: List[Product] = DB.withConnection { implicit connection => sql().map ( row => Product(row[Long]("id"), row[String]("name") ).toList}Play.api.Play.scalaimplicit def current: Application = maybeApplication... 54. Option Type List . >_< null . null ~ (null object pattern) Scala.Option.scala def apply[A](x: A): Option[A] = if (x == null) None else Some(x) // mothods flatMap, Flatten, map, foreach, idDefined, isEmpty... 55. Form (hide nothing) 1 Client GET /signup2 Signup.html3 Validate Fail su/index5 Redirectccess4 Create 56. Pros & Cons ( ) 57. Pros ! 58. Pros ! ... 59. ProsSimpleType Safe everywhereJava Scala 60. ConsSBTType Safe IDE 61. 2.3 Roadmap WebJar - Jquery, require.js, ecc JSUnit test Bootstrap JSON API Form Java JDK8 Compat Library Java 8 template 62. ? 63. ... 64. ... 65. ... : https://github.com/organizations/ScalaPlayers 66. ! GoogleGroups/ScalaKorea https://groups.google.com/forum/#!forum/scala-korea (2013-11-01 ) github.com/ScalaPlayers/SpringCampWithScala2013 SNS: facebook.com/choijeongyeol Email: [email protected] 67. Scala"Scala is deep where other languages are broad."