5장 플레이 프레임워크

클래식 버전으로 플레이 프레임워크 시작하기

  1. 프로젝트 생성
➜  play-2.2.6 ./play new playsample
       _
 _ __ | | __ _ _  _
| '_ \| |/ _' | || |
|  __/|_|\____|\__ /
|_|            |__/

play 2.2.6 built with Scala 2.10.3 (running Java 1.8.0_66), http://www.playframework.com

The new application will be created in /Users/seed/Downloads/play-2.2.6/playsample

What is the application name? [playsample]
> 

Which template do you want to use for this new application? 

  1             - Create a simple Scala application
  2             - Create a simple Java application

> 1
OK, application playsample is created.

Have fun!
  1. 프로젝트 실행
➜  playsample cd .. 
➜  play-2.2.6 cd playsample 
➜  playsample ../play run
Java HotSpot(TM) 64-Bit Server VM warning: ignoring option MaxPermSize=512M; support was removed in 8.0
[info] Loading project definition from /Users/seed/Downloads/play-2.2.6/playsample/project
[info] Set current project to playsample (in build file:/Users/seed/Downloads/play-2.2.6/playsample/)

--- (Running the application from SBT, auto-reloading is enabled) ---

[info] play - Listening for HTTP on /0:0:0:0:0:0:0:0:9000

(Server started, use Ctrl+D to stop and go back to the console...)

타입세이프 액티베이터 시작하기

➜  ~ activator ui
Checking for a newer version of Activator (current version 1.3.7)...
   ... our current version 1.3.7 looks like the latest.
Found previous process id: 88376
Local repository: activator-launcher-local @ file:/usr/local/Cellar/typesafe-activator/1.3.7/libexec/repository
Play server process ID is 95771
[info] play - Application started (Prod)
[info] play - Listening for HTTP on /127.0.0.1:8888
[info] a.e.s.Slf4jLogger - Slf4jLogger started

hello-play-scala 라 검색하면 hello-play-framework (Scala Only) 템플릿만 남는다. 하지만 템플릿이 있는대로 잘 되지 않는다.

/Users/seed/dev/storyzero/scala/hello-play-scala/build.sbt:15: error: reference to fork is ambiguous;
it is imported twice in the same scope by
import play.Project._
and import Keys._
fork in run := true
^
Type error in expression
Failed to load project.

플레이 애플리케이션의 구조

프레임워크의 구성

Akka?

Scala로 구현된 Concurrency 제어를 위해 Actor model을 도입한 프레임워크

Actor model?

Behavior, State, 그리고 Mailbox 로 구성된 Actor 를 기본 단위로 Message processing 을 이용하여 비동기적으로 실행하는 Model

Actor 의 특징

Actor 는 오로지 Message 로만 서로 간섭할 수 있고, 자원을 공유하지 않으며 State 제어도 할 수 없다. Message 는 Mailbox 에 순차적으로 쌓이며 실행될 Behavior 를 결정한다.

요청-응답 사이클

요청을 처리할 때 가장 먼저 conf/routes 파일을 거친다. 이 파일에서 요청된 URL을 처리할 컨트롤러 노드를 알 수 있다.

# Routes
# This file defines all application routes (Higher priority routes first)
# ~~~~

# An example controller showing a sample home page
GET     /                           controllers.HomeController.index
# An example controller showing how to use dependency injection
GET     /count                      controllers.CountController.count
# An example controller showing how to write asynchronous code
GET     /message                    controllers.AsyncController.message

# Map static resources from the /public folder to the /assets URL path
GET     /assets/*file               controllers.Assets.versioned(path="/public", file: Asset)

저자가 말하는 장점?

지원하는 API 를 한 눈에 확인할 수 있다. 애플리케이션의 디폴트 형태를 REST 방식으로 만들 수 있다.

설정파일 같지만 실제로 컴파일된다.

컨트롤러에서 요청 처리

package controllers

import javax.inject._
import play.api._
import play.api.mvc._

/**
 * This controller creates an `Action` to handle HTTP requests to the
 * application's home page.
 */
@Singleton
class HomeController @Inject() extends Controller {

  /**
   * Create an Action to render an HTML page with a welcome message.
   * The configuration in the `routes` file means that this method
   * will be called when the application receives a `GET` request with
   * a path of `/`.
   */
  def index = Action {
    Ok(views.html.index("Your new application is ready."))
  }

}
  • HomeController.index 메소드를 통해 요청이 들어오고 Action 블록에서 Result 오브젝트를 리턴한다.
    • Action An action is essentially a (Request[A] => Result) function that handles a request and generates a result to be sent to the client.
    • Result A simple result, which defines the response header and a body ready to send to the client.
  • Ok(views.html.index("Your new application is ready."))
    • HTTP status : 200
    • View : index.scala.html
    • Model : String

뷰 렌더링

@*
 * This template takes a single argument, a String containing a
 * message to display.
 *@
@(message: String)

@*
 * Call the the `main` template with two arguments. The first
 * argument is a `String` with the title of the page, the second
 * argument is an `Html` object containing the body of the page.
 *@
@main("Welcome to Play") {

    @*
     * Get an `Html` object by calling the built-in Play welcome
     * template and passing a `String` message.
     *@
    @play20.welcome(message, style = "Scala")

}

플레이에서 인증 처리

play-scala-intore with auth example


플레이 프레임워크 활용 팁

플레이에서 디버깅하기

play debug run

버전 컨트롤 관련 정리 사항

Generate gitignore


정리

  • Play framework 를 사용한 MVC 패턴의 애플리케이션
  • Scala 문법을 사용한 routes, template engine
    • 컴파일 타임에 오류를 검사하여 생산성 향상

그외

deploy production

  • Application Secret 생성, 적용 `` [play-scala-intro] $ playGenerateSecret [info] Generated new secret: ;=ns5c6?zeegK[>GjDJT[qxNVr7Xtdlk7z=v?UgM<AsLe@Lk35Jfh9g/iKT:U8n [success] Total time: 0 s, completed 2016. 3. 17 오후 6:12:23

in conf/application.conf play.crypto.secret = ~~~

[play-scala-intro] $ playUpdateSecret [info] Generated new secret: Uf=CKtL;?9W40tL9y^:PqQBi@ckneq<53nddE0wW_r`Hj5wZh[ UyzP[9^KFKdKN="" [info]="" Updating="" application="" secret="" in="" Users="" seed="" dev="" storyzero="" scala="" play-scala-intro-auth="" conf="" application.conf="" Replacing="" old="" secret:="" fQ51IlTi[52NqF<`NIQI?dLZw4kVJMLVptNLENx="">=?sGd<csxV:/^]6tTIQG[`2S [success] Total time: 0 s, completed 2016. 3. 17 오후 6:13:07

[play-scala-intro] $ dist ... [info] Your package is ready in /Users/seed/dev/storyzero/scala/play-scala-intro-auth/target/universal/play-scala-intro-1.0-SNAPSHOT.zip [info] [success] Total time: 20 s, completed 2016. 3. 17 오후 6:13:52 ```