On Github jamesward / introduction_to_the_play_framework-scala
Create a New Play App
activator new
IDE Support
activator idea
Run the App
activator ~run
Open the App
http://localhost:9000VERB PATH CONTROLLER_METHOD GET / controllers.Application.index() GET /foo controllers.Application.foo()
def index = Action {
Ok(index.render("Your new application is ready."))
}
@(message: String)
@main("Welcome to Play 2.0") {
@message
}
Run All Tests Once
activator test
Run All Tests Continuously
activator ~test
Run One Test
activator "test-only my.namespace.MySpec"
Run Failed Tests
activator test-quick
"render index template" in new WithApplication {
val html = views.html.index("Coco")
contentAsString(html) must contain("Hello Coco")
}
object FunctionalExampleControllerSpec extends PlaySpecification {
"respond to the index Action" in new WithApplication {
val result = controllers.Application.index()(FakeRequest())
status(result) must equalTo(OK)
contentType(result) must beSome("text/plain")
contentAsString(result) must contain("Hello Bob")
}
}
"respond to the index Action" in new WithApplication {
val Some(result) = route(FakeRequest(GET, "/Bob"))
status(result) must equalTo(OK)
contentType(result) must beSome("text/html")
charset(result) must beSome("utf-8")
contentAsString(result) must contain("Hello Bob")
}
case class Foo(name: String)
object Foo {
implicit val fooFormat = Json.format[Foo]
}
def foo = Action {
Ok(Foo("asdf"))
}
object Foo {
implicit val fooWrites = Json.writes[Foo]
implicit val fooReads: Reads[Foo] = (__ \ "name").read[String](minLength[String](5)).map(Foo(_))
}
Json.parse("""{"name": "asdf"}""").validate[Foo]
// JsError(List((/name,List(ValidationError(error.minLength,WrappedArray(5))))))
val foo = Json.obj("name" -> "Bob")
val transformer = (__ \ "name").json.put(JsString("foo"))
val newFoo = foo.transform(transformer)
newFoo.map(Ok(_)).getOrElse(BadRequest)
val js = json"""{ "foo" : "bar", "foo2" : 123 }"""
js match {
case json"""{ "foo" : $a, "foo2" : $b }""" => Some(a -> b)
case _ => None
}
addSbtPlugin("com.typesafe.sbt" % "sbt-coffeescript" % "1.0.0")
assets/javascripts/foo.coffee
<script src='@routes.Assets.at("javascripts/foo.min.js")'></script>
"org.webjars" % "jquery" % "2.1.1"Use a WebJar
<script src='@routes.Assets.at("lib/jquery/jquery.min.js)'></script>
def foo = Action {
Ok("foo")
}
def foo = Action.async {
Future(Ok("foo"))
}
def pause(duration: Int) = Action.async {
Promise.timeout(Ok(duration.toString), duration seconds)
}
val futureResponse: Future[Response] = WS.url("http://www.foo.com").get
def foo = Action.async {
val futureResponse = WS.url("http://www.foo.com").get
futureResponse.map { response =>
Ok(response.body)
}
}
def foo = Action.async {
val futureJW = WS.url("http://www.jamesward.com").get
val futureTwitter = WS.url("http://www.twitter.com").get
for {
jw <- futureJW
twitter <- futureTwitter
} yield Ok(jw.response.body + twitter.response.body)
}
def events = Action {
val (enumerator, channel) = Concurrent.broadcast[String]
Akka.system.scheduler.schedule(Duration.Zero, 1.second, new Runnable {
def run() = channel.push("hello")
})
Ok.feed(enumerator &> EventSource()).as(EVENT_STREAM)
}
$ ->
events = new EventSource("/events")
events.onmessage = (e) ->
console.log(e.data)
def echoWs = WebSocket.using[String] { request =>
val (enumerator, channel) = Concurrent.broadcast[String]
val in = Iteratee.foreach[String](channel.push)
(in, enumerator)
}
$ ->
ws = new WebSocket("ws://localhost:9000/echo")
ws.onopen = () ->
ws.send("foo")
ws.onmessage = (message) ->
console.log(message.data)