I've started learning scala and the play framework. I downloaded the sample project from the play framework site. I have a newbie question because I cannot understand the following syntax:
def count = Action { Ok(counter.nextCount().toString) }
What exactly does it do? Action is implemented function in BaseController, where action builder is assigned.
What is the content the beetwen braces for? Wat do the braces mean in this context?
In playframework, requests are handled by Actions. When you invoke Action { ... }, you are actually invoking play.api.mvc.Action helper object to create Action values.
object Action extends ActionBuilder[Request] { ... }
If you look closely to Action object, it extends to play.api.mvc.ActionBuilder trait. This trait contains various overloaded apply methods that creates Action values. Therefore, when you are invoking Action{ ... } you are actually invoking Action.apply({...}) and this apply method is inherited from ActionBuilder trait. If you look into ActionBuilder trait, you will see various higher ordered apply functions.
Now in your case, def count = Action { Ok(counter.nextCount().toString) }
You are actually invoking apply method with default content and no request parameter.
final def apply(block: => Result): Action[AnyContent] = apply(_ => block)
That means, you are providing block { Ok(counter.nextCount().toString) } which return Ok Result.
What is the content the beetwen braces for? Wat do the braces mean in this context?
When you do Action { Ok(counter.nextCount().toString) }, you are actually invoking:
Action.apply(Ok(counter.nextCount().toString))
In scala, apply method is a factory method and therefore you don't have to essentially call apply method, therefore you can also do Action(Ok(counter.nextCount().toString)). Additionally, if your function takes only single parameter, you can replace () brackets with curly braces {}. i.e. you can do Action{Ok(counter.nextCount().toString)}.
I would suggest to look into function literals, higher ordered functions, by-name parameter, method currying etc. So, that you will have more insight in these.
The source code will give you the details:
/**
* Constructs an `Action` with default content, and no request parameter.
*
* For example:
* {{{
* val hello = Action {
* Ok("Hello!")
* }
* }}}
*
* #param block the action code
* #return an action
*/
final def apply(block: => Result): Action[AnyContent] =
apply(BodyParsers.utils.ignore(AnyContentAsEmpty: AnyContent))(_ => block)
It's equivalent to def count = Action.apply(Ok(counter.nextCount().toString))
Related
When you see code that follows this pattern:
def index = Action { request =>
// ..
}
Action trait: https://github.com/playframework/playframework/blob/master/framework/src/play/src/main/scala/play/api/mvc/Action.scala#L65
When looking at this code, how would you know that the request object is available to use within the code block? (is there a intellij shortcut for this?)
Can someone please create a miniature example of where you can mimic this pattern so I can understand how this works, and if you can explain in technical terms what is going on?
The Action trait is not of interest here. Instead, because the body of the index method must be a value, not a type, you are looking at the Action object. You can learn more about objects here. Let's first simplify the syntax by removing syntactic sugar, i.e. making the program behave the same but with simpler constructs. If you try to call an object as if it were a method, what really happens is that .apply is inserted for you by the compiler:
def index = Action.apply((request) => {
// ..
})
This may be more familiar; the apply method is being called on the Action object, passing a lambda function that takes a request. And obviously, an argument to a lambda is always available within that lambda. That's the point of them.
The lambda in this case is also known as a callback. A simple example that clarifies these features follows:
object WithAnswer {
def apply(f: Int => Unit): Unit =
f(42)
}
def printAnswer() = WithAnswer { answer =>
println(answer)
}
This is called as Loan pattern
withWriter creates a writer for the user and then ensures the resource (writer) is properly closely after using.
All that user has to do is just use the writer and write something to the file
def withWriter(file: File)(f: Writer => Unit): Unit = {
val writer = new PrintWriter(file)
try {
f(writer)
} finally {
writer close
}
}
Usage:
withWriter(new File("some_fix.txt") { writer =>
writer println("write something")
}
I am developing Play application and I've just started with Scala. I see that there is this word Action after the equals sign in the function below and before curly brace.
def index = Action {
Ok(views.html.index("Hi there"))
}
What does this code do? I've seen it used with def index = { but not with the word before the curly brace.
I would assume that the name of the function is index. But I do not know what the word Action does in this situation.
This word is a part of Play Framework, and it's an object, which has method apply(block: ⇒ Result), so your code is actually:
def index: Action[AnyContent] = Action.apply({
Ok.apply(views.html.index("Hi there"))
})
Your index method returns an instance of the class Action[AnyContent].
By the way, you're passing a block of code {Ok(...)} to apply method, which (block of code) is actually acts as anonymous function here, because the required type for apply's input is not just Result but ⇒ Result, which means that it takes an anonymous function with no input parameters, which returns Result. So, your Ok-block will be executed when container, received your instance of class Action (from index method), decided to execute this block. Which simply means that you're just describing an action here - not executing - it will be actually executed when Play received your request - and find binding to your action inside routing file.
Also, you don't have to use def here as you always return same action - val or lazy val is usually enough. You will need a def only if you actually want to pass some parameter from routing table (for instance):
GET /clients/:id controllers.SomeController.index(id: Long)
def index(id: Long) = Action { ... } // new action generated for every new request here
Another possible approach is to choose Action, based on parameter:
def index(id: Long) = {
if (id == 0) Action {...} else Action{...}
}
But uasually you can use routing table itself for that, which is better for decoupling. This example just shows that Action is nothing more than return value.
Update for #Kazuya
val method1 = Action{...} //could be def too, no big difference here
// this (code inside Action) gonna be called separately after "index" (if method2 is requested of course)
// notice that it needs the whole request, so it (request) should be completely parsed at the time
val method2 = Action{ req => // you can extract additional params from request
val param1 = req.headers("header1")
...
}
//This is gonna be called first, notice that Play doesn't need the whole request body here, so it might not even be parsed on this stage
def index(methodName: String) = methodName match {
case "method1" => method1
case "method2" => method2
}
GWT/Scala.js use simillar approach for client-server interaction. This is just one possible solution to explain importance of the parameter "methodName" passed from routing table. So, action could be thought as a wrapper over function that in its turn represents a reference to OOP-method, which makes it useful for both REST and RPC purposes.
The other answers deal with your specific case. You asked about the general case, however, so I'll attempt to answer from that perspective.
First off, def is used to define a method, not a function (better to learn that difference now). But, you're right, index is the name of that method.
Now, unlike other languages you might be familiar with (e.g., C, Java), Scala lets you define methods with an expression (as suggested by the use of the assignment operator syntax, =). That is, everything after the = is an expression that will be evaluated to a value each time the method is invoked.
So, whereas in Java you have to say:
public int three() { return 3; }
In Scala, you can just say:
def three = 3
Of course, the expression is usually more complicated (as in your case). It could be a block of code, like you're more used to seeing, in which case the value is that of the last expression in the block:
def three = {
val a = 1
val b = 2
a + b
}
Or it might involve a method invocation on some other object:
def three = Numbers.add(1, 2)
The latter is, in fact, exactly what's going on in your specific example, although it requires a bit more explanation to understand why. There are two bits of magic involved:
If an object has an apply method, then you can treat the object as if it were a function. You can say, for example, Add(1, 2) when you really mean Add.apply(1,2) (assuming there's an Add object with an apply method, of course). And just to be clear, it doesn't have to be an object defined with the object keyword. Any object with a suitable apply method will do.
If a method has a single by-name parameter (e.g., def ifWaterBoiling(fn: => Tea)), then you can invoke the method like ifWaterBoiling { makeTea }. The code in that block is evaluated lazily (and may not be evaluated at all). This would be equivalent to writing ifWaterBoiling({ makeTea }). The { makeTea } part just defines an expression that gets passed in, unevaluated, for the fn parameter.
Its the Action being called on with an expression block as argument. (The apply method is used under the hood).
Action.apply({
Ok("Hello world")
})
A simple example (from here) is as follows (look at comments in code):
case class Logging[A](action: Action[A]) extends Action[A] {
def apply(request: Request[A]): Result = {// apply method which is called on expression
Logger.info("Calling action")
action(request) // action being called on further with the request provided to Logging Action
}
lazy val parser = action.parser
}
Now you can use it to wrap any other action value:
def index = Logging { // Expression argument starts
Action { // Action argument (goes under request)
Ok("Hello World")
}
}
Also, the case you mentioned for def index = { is actually returning Unit like: def index: Unit = {.
I'm using Play 2.x and found the following syntax in action handlers e.g.
object Application extends Controller {
/**
* Index action handler
*/
def index = Action { implicit request =>
Ok(Json.obj("one" -> "two"))
}
}
Here I understand everything except the = Action which is not the type of the function, because the function return type is play.api.mvc.Result. So what does the = Action mean?
To make the understanding worse I now introduced authentication and based on examples changed my Application to:
object Application extends Controller with Secured {
/**
* Index action handler
*/
def index = IsAuthenticated { username => implicit request =>
Ok(Json.obj("one" -> "two"))
}
}
This works but why the Action is no longer necessary? was it necessary at all? how can I combine several of these types (whatever they mean): Action or DBAction, IsAuthenticated etc?
Action is not a type, it is a function. If it were a type the signature for index would look like
def index: Action = { implicit request =>
Notice the addition of the : and the location of the =
The relevant documentation states an Action is a
function that handles a request and generates a result to be sent to
the client
As you noticed you are returning a play.api.mvc.Result
Ok now thanks to a colleague I understood what it is. That syntax that simply means returning an object, in this case an object of type Action and the action takes as constructor argument a function that takes as input a Request and returns a SimpleResult, it can be rewritten as e.g.
object Application extends Controller {
/**
* Index action handler
*/
def index : Action[AnyContent] = {
Action(implicit request => Ok(Json.obj("one" -> "two")))
}
}
What makes it actually confusing is that in Scala they can switch between parenthesis and curly brackets somewhat indistinctly. Therefore makes it tricky to realize it is not a function body what I was looking at but a constructor parameter to an action (which is an anonymous function)
I've the following code:
trait AcceptExtractors {
/**
* Common extractors to check if a request accepts JSON, Html, etc.
* Example of use:
* {{{
* request match {
* case Accepts.Json() => Ok(toJson(value))
* case _ => Ok(views.html.show(value))
* }
* }}}
*/
object Accepts {
import play.api.http.MimeTypes
val Json = Accepting(MimeTypes.JSON)
val Html = Accepting(MimeTypes.HTML)
val Xml = Accepting(MimeTypes.XML)
val JavaScript = Accepting(MimeTypes.JAVASCRIPT)
}
}
Is there any way to extend the Accepts object?
Thank you!
Nope.
Objects are single values. If they could be extended, they would not be singletons (*). The class generated to represent them is final, so even if you knew its name (not hard to find out), you could not extend it.
(*) Objects are only truly singletons when defined at global scope or nested strictly within other objects leading back to a global one.
No, but you could make Accepts a trait which you can extend.
I am new to Scala, and am learning it by going over some Play code. I have had a good read of the major concepts of Scala and am comfortable with functional programming having done some Haskell and ML.
I am really struggling to read this code, at the level of the syntax and the programming paradigms alone. I understand what the code is supposed to do, but not how it does it because I can't figure out the syntax.
// -- Home page
def index(ref: Option[String]): Action[AnyContent] = Prismic.action(ref) { implicit request =>
for {
someDocuments <- ctx.api.forms("everything").ref(ctx.ref).submit()
} yield {
Ok(views.html.index(someDocuments))
}
}
(Prismic is an API separate to Play and is not really that relevant). How would I describe this function (or is it a method??) to another developer over the phone: in other words, using English. For example in this code:
def add(a: Int, b: Int): Int = a + b
I would say "add is a function which takes two integers, adds them together and returns the result as another integer".
In the Play code above I don't even know how to describe it after getting to "index is a function which takes an Option of a String and returns an Action of type AnyContent by ....."
The bit after the '=' and then the curly braces and the '=>' scare me! How do I read them? And is the functional or OO?
Thanks for your assistance
Let's reduce it to this:
def index(ref: Option[String]): Action[AnyContent] = Prismic.action(ref)(function)
That's better, isn't it? index is a function from Option of String to Action of AnyContent (one word), which calls the action method of the object Prismic passing two curried parameters: ref, the parameter that index received, and a function (to be described).
So let's break down the anonymous function:
{ implicit request =>
for {
someDocuments <- ctx.api.forms("everything").ref(ctx.ref).submit()
} yield {
Ok(views.html.index(someDocuments))
}
}
First, it uses {} instead of () because Scala allows one to drop () as parameter delimiter if it's a single parameter (there are two parameter lists, but each has a single parameter), and that parameter is enclosed in {}.
So, what about {}? Well, it's an expression that contains declarations and statements, with semi-colon inference on new lines, whose value is that of the last statement. That is, the value of these two expressions is the same, 3:
{ 1; 2; 3 }
{
1
2
3
}
It's a syntactic convention to use {} when passing a function that extends for more than one line, even if, as in this case, that function could have been passed with just parenthesis.
The next thing confusing is the implicit request =>, Let's pick something simpler:
x => x * 2
That's pretty easy, right? It takes one parameter, x, and returns x * 2. In our case, it is the same thing: the function takes one parameter, request, and returns this:
for (someDocuments <- somethingSomething())
yield Ok(views.html.index(someDocuments))
That is, it calls some methods, iterate over the result, and map those results into a new value. This is a close equivalent to Haskell's do notation. You can rewrite it like below (I'm breaking it down into multiple lines for readability):
ctx
.api
.forms("everything")
.ref(ctx.ref)
.submit()
.map(someDocuments => Ok(views.html.index(someDocuments)))
So, back to our method definition, we have this:
def index(ref: Option[String]): Action[AnyContent] = Prismic.action(ref)(
implicit request =>
ctx
.api
.forms("everything")
.ref(ctx.ref)
.submit()
.map(someDocuments => Ok(views.html.index(someDocuments)))
)
The only remaining question here is what that implicit is about. Basically, it makes that parameter implicitly available through the scope of the function. Presumably, at least one of these method calls require an implicit parameter which is properly fielded by request. I could drop the implicit there an pass request explicitly, if I knew which of these methods require it, but since I don't, I'm skipping that.
An alternate way of writing it would be:
def index(ref: Option[String]): Action[AnyContent] = Prismic.action(ref)({
request =>
implicit val req = request
ctx
.api
.forms("everything")
.ref(ctx.ref)
.submit()
.map(someDocuments => Ok(views.html.index(someDocuments)))
})
Here I added {} back because I added a declaration to the body of the function, though I decided not to drop the parenthesis, which I could have.
Something like this:
index is a function which takes an Option of a String and returns an Action of type AnyContent. It calls the method action that takes as a first argument an Option and as a second argument a method that assumes an implicit value request of type Request is in scope. This method uses a For-comprehension that calls the submit method which returns an Option or a Future and then in case its execution is successful, it yields the result Ok(...) that will be wrapped in the Action returned by the action method of Prismic.
Prismic.action is a method that takes 2 groups of arguments (a.k.a. currying).
The first is ref
The second is { implicit request => ...}, a function defined in a block of a code
more information on Action