Reputation: 13
I have been studying and playing with Scala and at the same time I have been trying to learn Play! and especially Scala version play.
I understand the apply-methods of an object and even passing code block to Trait or Class. But in all examples Action-code block example is something like :
def index = Action {
Ok("Got request [" + request + "]")
}
So in here we are using Action-companion object helper and we are passing code block to this companion objects apply-function ?
But what I don't understand is where to "request" is populated from ? This is something I have encountered with Scala, some "mysterious" magic just happens but I need to understand it. :)
So if someone could explain this to Scala and Play! newbie your help would be appreciated.
Upvotes: 1
Views: 995
Reputation: 8901
It's actually not so magical (in this instance at least). Controllers receive a request and produce a response. In Play you can write this if you don't need to access or use any of the request information:
def index = Action {
Ok("hello, world") // Not using the request!
}
But the code as you've written it (as of now) won't actually compile because, as you say, the request isn't given. Instead you need to do this:
def index = Action { request =>
Ok("Got request [" + request + "]")
}
i.e. the request is a parameter to a function that returns a Result
(the Ok
).
And yes, you're right, it's equivalent to writing:
def index = Action.apply({ request =>
Ok("Got request [" + request + "]")
})
or even more explicitly:
def myAction[T]: (Request[T] => Result) = request => Ok("Got request [" + request + "]")
def index = Action.apply(myAction)
The index
is not a function that returns a response directly. It is a function the framework calls to obtain a handler for a request (the Action
). That handler can then be invoked with the incoming request to produce a response.
There are other variations. By default, the content of the request (i.e. the body) is handled as a general purpose AnyContent
. If you want to explicitly parse the body in some particular way, for instance as JSON, you can pass a BodyParser
as the first (curried) argument:
def index = Action(myBodyParser) { request =>
Ok("Got request [" + request + "]")
}
Note: it's common to make the request an implicit parameter so it will, for example, get automatically passed to templates:
def index = Action { implicit request =>
Ok(views.html.mypage())
}
For some template code like:
@()(implicit request: RequestHeader)
<h1>I was called at @request.path</h1>
Upvotes: 4