播放:如何实施动作组合 [英] Play: How to implement action composition
问题描述
给出以下ActionBuilder
实现:
class SignedRequest[A](request: Request[A]) extends WrappedRequest[A](request) {}
object SignedAction extends ActionBuilder[SignedRequest] {
def invokeBlock[A](request: Request[A], block: SignedRequest[A] => Future[SimpleResult]) = {
block(new SignedRequest(request))
}
}
class SecuredRequest[A](request: Request[A]) extends WrappedRequest[A](request) {}
object SecuredRequest extends ActionBuilder[SecuredRequest] {
def invokeBlock[A](request: Request[A], block: SecuredRequest[A] => Future[SimpleResult]) = {
block(new SecuredRequest(request))
}
}
如何合并它们?我尝试了以下方法...
How do I combine them? I've tried the following...
object MyController extends Controller {
def doSomething = SignedAction.async(parse.json) {
SecuredAction.async(parse.json) { implicit request =>
Future.successful(Ok)
}}
}
...但是我总是收到以下错误消息:
... but I always get the following error message:
/home/j3d/test/controllers/MyController.scala:37: type mismatch;
[error] found : play.api.mvc.Action[play.api.libs.json.JsValue]
[error] required: scala.concurrent.Future[play.api.mvc.SimpleResult]
[error] SecuredAction.async(parse.json) {
^
我错过了什么吗? Tx.
Am I missing something? Tx.
推荐答案
函数async
期望Future[SimpleResult]
,但是嵌套的SecuredAction.async
返回顶部SignedAction.async
的Action
(请注意,您省略了将请求声明为class
并且SignedAction
声明了两次的示例代码.
Function async
is expecting a Future[SimpleResult]
, but the nested SecuredAction.async
is returning an Action
to the top SignedAction.async
(notes that in your sample code you omit to declare requests as class
and SignedAction
is declared twice).
您可以将嵌套的SecuredAction
应用于SignedAction
中的结果,方法是将其应用于已签名的请求.
You can compose result of nested SecuredAction
within SignedAction
by applying it to the signed request.
package controllers
import scala.concurrent.Future
import play.api._
import play.api.mvc._
case class SignedRequest[A](request: Request[A])
extends WrappedRequest[A](request) {}
object SignedAction extends ActionBuilder[SignedRequest] {
def invokeBlock[A](request: Request[A],
block: SignedRequest[A] => Future[Result]) =
block(new SignedRequest(request))
}
case class SecuredRequest[A](request: Request[A])
extends WrappedRequest[A](request) {}
object SecuredAction extends ActionBuilder[SecuredRequest] {
def invokeBlock[A](request: Request[A],
block: SecuredRequest[A] => Future[Result]) =
block(new SecuredRequest(request))
}
object MyController extends Controller {
def doSomething = SignedAction.async(parse.json) { signedReq =>
SecuredAction.async(parse.json) { implicit securedReq =>
Future.successful(Ok)
} apply signedReq
}
}
在没有ActionBuilder
的情况下也可以完成这种动作组合(这可能会导致一些额外的复杂性).
Such action composition can also be done without ActionBuilder
(which can lead to some extra complexity).
package controllers
import scala.concurrent.Future
import play.api._
import play.api.mvc._
case class SignedRequest[A](request: Request[A])
case class SecuredRequest[A](request: Request[A])
object MyController extends Controller {
def Signed[A](bodyParser: BodyParser[A])(signedBlock: SignedRequest[A] => Future[Result]): Action[A] = Action.async(bodyParser) { req =>
signedBlock(SignedRequest(req))
}
def Secured[A](bodyParser: BodyParser[A])(securedBlock: SecuredRequest[A] => Future[Result]): Action[A] = Action.async(bodyParser) { req =>
securedBlock(SecuredRequest(req))
}
def doSomething = Signed(parse.json) { signedReq =>
Secured(parse.json) { implicit securedReq =>
Future.successful(Ok)
} apply signedReq.request
}
}
也可以围绕Future[Result]
进行构图:
package controllers
import scala.concurrent.Future
import play.api._
import play.api.mvc._
import play.api.libs.json.JsValue
case class SignedRequest[A](request: Request[A])
case class SecuredRequest[A](request: Request[A])
object MyController extends Controller {
def Signed[A](signedBlock: SignedRequest[A] => Future[Result])(implicit req: Request[A]): Future[Result] = signedBlock(SignedRequest(req))
def Secured[A](signedBlock: SecuredRequest[A] => Future[Result])(implicit req: Request[A]): Future[Result] = signedBlock(SecuredRequest(req))
def doSomething = Action.async(parse.json) { implicit req =>
Signed[JsValue] { signedReq =>
Secured[JsValue] { securedReq => Future.successful(Ok) }
}
}
}
这篇关于播放:如何实施动作组合的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!