pramesh
pramesh

Reputation: 1964

Explain request passing in play framework

I was trying this in playframework. When I came through this part, at first it seemed pretty straightforward but while trying to trace it I'm not able to understand how this works. I know what kind of parameter is accepted by apply method of Action but I couldn't get how request is available and how it can be passed to Ok. Can anyone show analogous example with simple definition in scala.

@Singleton
class HomeController @Inject()(configuration: Configuration, cc: ControllerComponents)(implicit assetsFinder: AssetsFinder)
  extends AbstractController(cc) {
  def tweets = Action { implicit request =>
    Ok(s"request is $request")
  }
}

Thanks in advance

Upvotes: 0

Views: 487

Answers (2)

Dmytro Mitin
Dmytro Mitin

Reputation: 51693

Object Action extends trait DefaultActionBuilder extending trait ActionBuilder. The latter has method

apply(block: R[B] => Result): Action[B]

In your case request is of type Request[AnyContent] i.e. R is Request and B is AnyContent, Ok(s"request is $request") is of type Result,

Action { implicit request =>
  Ok(s"request is $request")
}

is of type Action[B] i.e. Action[AnyContent]. So the syntax is just apply method of an object and a lambda as an argument of the method.

What is the apply function in Scala?

foo(implicit x => ???) is the same as foo(x => { implicit val x_ = x; ??? }).

Implicit keyword before a parameter in anonymous function in Scala

Ok is just new Status(OK) i.e. new Status(200) and class Status has method

def apply[C](content: C)(implicit writeable: Writeable[C]): Result

i.e. C is now String and content is s"request is $request" (i.e. string "request is " + request.toString).

If you use IDE you can investigate similar inheritance hierarchies and types yourself.

Upvotes: 1

mfirry
mfirry

Reputation: 3692

I'll try and simplify a bit:

trait A extends (String => String) { self => def apply() = this }

A effectively extends a function from String to String.

object A { def apply(f: String => String): A = new A { def apply(x: String) = f(x) } }

A's companion object actually implements A.

So you can now do this:

val f: String => String = _.toLowerCase
A(f)

This is valid Scala code.

You define f (toLowerCase on strings) and you pass it to the apply method of A.

This can also be written like this:

A { s => s.toLowerCase } // this way of putting it should remind you of Action { request => ... }

This is exactly how Play Action and EssentialAction works.

The other thing you ask is about Ok.

Ok is defined as a short version of Status with a set status code (200) and the given body (so something like Ok("Hello world!") will work.

On top of this there's the usual string interpolation you should know about.

Upvotes: 1

Related Questions