user434983
user434983

Reputation: 13

Play 2.x Scala Controller clarification needed

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

Answers (1)

Mikesname
Mikesname

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

Related Questions