Scala Play 2.3 Getting request back in scope - scala

Sorry for my lack of correct terminology, but hopefully the questions is at least understandable :)
I'm implementing a trait which is called out to by a library - so I don't have access over the "middle" of the code.
Controller -> Action (get request in scope) -> Library -> Trait -> my code to save to database
Trying
def insert(newRecord: Token)(implicit request: play.api.mvc.Request[Any]) = database.withSession { implicit db:Session => {
Gives a compile error:
Cannot find any HTTP Request here
Is there anyway to get the request back in scope?
The code:
Specifically, I'm using play2-oauth2-provider, and the relevant pieces of code as I understand are
Get request in scope in Action, this is working correctly
def accessToken = Action.async {
implicit request =>
val header = request.remoteAddress
issueAccessToken(new UserOauth())
The request then gets passed through the library (a few times) - the last point in the library code which request is still in scope is a call -
handler.handleRequest(request, dataHandler)
override def handleRequest[U](request: AuthorizationRequest, dataHandler: DataHandler[U]): GrantHandlerResult = {
.....
issueAccessToken(dataHandler, authInfo)
}
The last line of handleRequest calls to issueAccessToken.
By my understanding, this is where the reference to request is lost, and my question is - "is there any way to get it back." Again, I can't change this code as its in a library.
def issueAccessToken[U](dataHandler: DataHandler[U], authInfo: AuthInfo[U]): GrantHandlerResult = {
...
dataHandler.createAccessToken(authInfo)
}
My code is then
class UserOauth extends DataHandler[Credentials] {
def createAccessToken....
Which eventually calls my data model - where I would like to get something from the request object
Thanks,
Brent

The insert function is requiring a request from the context/caller (that's what the implicit request means there). Not finding a request provided as implicit, the compiler raise the error.
To fix it, you have to declare an implicit for current request (provided by Play Action) in the code calling insert. implicit must be corresponding side by side, between caller and callee, e.g.
def myAction = Action { implicit req => // instead of just Action { req => ... }
insert(myRec)
}
def myAsyncAction = Action async { implicit req =>
Future { insert(myRec)
}
Any implicit parameter is looking for a matching implicit value (def or val) in current implicit scope (from the caller).
Making everying 'explicit' can help to understand insert (and is also sometime better as code), as an implicit parameter is by first a parameter, so following code is also right.
def myAction = Action { req => insert(myRecord)(req) }

Related

What does the word "Action" do in a Scala function definition using the Play framework?

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 = {.

Scala what does the "def function = Type {" mean?

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)

implicit keyword in Play Action

Can someone explain to me what's the use of implicit keyword in the following Play Action:
def index = Action { implicit request =>
Async {
val cursor = collection.find(
BSONDocument(), BSONDocument()).cursor[Patient]
val futureList = cursor.toList
futureList.map { patients => Ok(Json.toJson(patients)) }
}
}
Thanks in advance.
In all Scala (not just Play), an argument to an anonymous function can be marked implicit just as with methods. Within the body of the function, the implicit parameter is visible and can be resolved to an appropriate value in scope.
In this case, request is the argument of the anonymous function that describes what the action will do. The implicit lets the function be called with any value of type Request that happens to be in scope so you don't have to provide the Request instance yourself. You can trust it will be there so you can focus on the work of handling the request.

Scala Implicit parameters by passing a function as argument To feel the adnvatage

I try to feel the advantage of implicit parameters in Scala. (EDITED: special case when anonymous function is used. Please look at the links in this question)
I try to make simple emulation based on this post. Where explained how Action works in PlayFramework. This also related to that.
The following code is for that purpose:
object ImplicitArguments extends App {
implicit val intValue = 1 // this is exiting value to be passed implicitly to everyone who might use it
def fun(block: Int=>String): String = { // we do not use _implicit_ here !
block(2) // ?? how to avoid passing '2' but make use of that would be passed implicitly ?
}
// here we use _implicit_ keyword to make it know that the value should be passed !
val result = fun{ implicit intValue => { // this is my 'block'
intValue.toString // (which is anonymous function)
}
}
println(result) // prints 2
}
I want to get "1" printed.
How to avoid passing magic "2" but use "1" that was defined implicitly?
Also see the case where we do not use implicit in definition, but it is there, because of anonymous function passing with implicit.
EDITED:
Just in case, I'm posting another example - simple emulation of how Play' Action works:
object ImplicitArguments extends App {
case class Request(msg:String)
implicit val request = Request("my request")
case class Result(msg:String)
case class Action(result:Result)
object Action {
def apply(block:Request => Result):Action = {
val result = block(...) // what should be here ??
new Action(result)
}
}
val action = Action { implicit request =>
Result("Got request [" + request + "]")
}
println(action)
}
Implicits don't work like this. There is no magic. They are just (usually) hidden parameters and are therefore resolved when invoking the function.
There are two ways to make your code work.
you can fix the implicit value for all invocations of fun
def fun(block: Int=>String): String = {
block(implicitly[Int])
}
implicitly is a function defined in Predef. Again no magic. Here's it's definition
def implicitly[A](implicit value: A) = value
But this means it will resolve the implicit value when declaring the fun and not for each invocation.
If you want to use different values for different invocations you will need to add the implicit paramter
def fun(block: Int=>String)(implicit value: Int): String = {
block(value)
}
This will now depend on the implicit scope at the call site. And you can easily override it like this
val result = fun{ _.toString }(3)
and result will be "3" because of the explicit 3 at the end. There is, however, no way to magically change the fun from your declaration to fetch values from implicit scope.
I hope you understand implicits better now, they can be a bit tricky to wrap your head around at first.
It seems that for that particular case I asked, the answer might be like this:
That this is not really a good idea to use implicit intValue or implicit request along with implicitly() using only one parameter for the function that accept (anonymous) function.
Why not, because:
Say, if in block(...) in apply() I would use implicitly[Request], then
it does not matter whether I use "implicit request" or not - it will use
request that is defined implicitly somewhere. Even if I would pass my
own request to Action { myOwnRequest =Result }.
For that particular case is better to use currying and two arguments and.. in the second argument - (first)(second) to use implicit
Like this:
def apply(block:Request => Result)(implicit request:Request):Action2
See my little effort around this example/use case here.
But, I don't see any good example so far in regards to how to use implicit by passing the (anonymous) function as argument (my initial question):
fun{ implicit intValue => {intValue.toString}
or that one (updated version):
val action = Action { implicit request =>
Result("Got request [" + request + "]")
}

How to have scala infer types from a java method

I am trying to consume an external Java Service API in Scala by writing a wrapper around it. Each API call has a Request class and Response class, as well as a factory method to setup a call in the underlaying java client i.e.
val caller = serviceClient.newDoSomething()
val request = DoSomethingRequest(...)
val response = caller.call(request)
where response is of type DoSomethingResponse.
This pattern is repeated for a bunch of different operations only varying in the names of the request/response classes and the factory method. I would like to DRY up the code and use the type inference, while noting a key observation that java method
caller.call is of type Request => Response.
Given that I've attempted the following:
class ServiceAPI {
val client = Service.getDefaultClient
def serviceCall[Req, Resp](auth: String, caller: Req => Resp)
(func: Req => Unit)(implicit m:Manifest[Req]):Resp = {
val request = m.erasure.newInstance.asInstanceOf[Req]
request.setAuth(auth)
func(request)
caller(request)
}
}
What I would like to end up with is a consumable scala API that can be invoked like so:
serviceCall(myAuth, client.newEventCall.call(_)) {
_.setFoo("foo") // On request
_.setBar(2) // On request
}
I was hoping that by providing the partial function client.newEventCall.call(_) Scala would be able to fully infer Req and Resp from it and then properly invoke the rest.
However, this fails with:
error: missing parameter type for expanded function ((x$4) => client.newEventCall.call(x$4))
Obviously I can provide the type manually via:
serviceCall(myAuth, client.newEventCall.call(_:EventRequest)) { ... }
but I would like to avoid that. Any ideas?
Also bonus points if this can be further simplified.