必需:play.api.mvc.Request [?] => play.api.mvc.Result

时间:2018-07-25 23:09:00

标签: scala playframework

我正在迁移到Play 2.6,并具有以下曾经有效的API包装器功能:

trait API {
    self: Controller =>

    def api(businessLogic: Request[AnyContent] => Any): Action[AnyContent] = apiWithBody(parse.anyContent)(businessLogic)

    def apiWithBody[A](bodyParser: BodyParser[A])(businessLogic: Request[A] => Any): Action[A] = Action(bodyParser) {
        implicit request =>
        {
            val apiResult = businessLogic(request)
            val start = new java.util.Date().getTime
            val actionDuration = (new java.util.Date().getTime - start)
            val response = resultFrom(apiResult, request, actionDuration)    // Returns a Result
            response
        }
    }
}

由Controller函数调用,例如:

object Accounts extends Controller with API {

    def all = superUser {
        implicit principal =>
            api {
                request =>
                    models.Account.all
            }
    }
}

其中superUser是主体(用户)类型“ admin”。

并出现以下编译器错误:

[error] type mismatch;
[error]  found   : play.api.mvc.Action[play.api.mvc.AnyContent]
[error]  required: play.api.mvc.Request[?] => play.api.mvc.Result
[error]             api {
[error]                 ^

我正在使用sbt 1.1.5和Scala 2.11.8进行构建。

我猜测[?]表示编译器不知道需要哪种类型,但我不明白什么是错误的。我已经搜索了此问题,但未找到该问题的具体答案。

此外,我遇到一个错误:

[error]  could not find implicit value for parameter parser: play.api.mvc.BodyParser[Any]
[error]     def all = superUser {
[error]                         ^

我已作为单独的问题发布(请参见could not find implicit value for parameter parser: play.api.mvc.BodyParser[Any]),但可能与此处有关?

def superUser[A](f: => Principal => Request[A] => Result)(implicit parser: BodyParser[A]): SecureAction[A] = {
    _superUser {
        user =>
            implicit val principal = data.Principal(user)
            Action(parser)(request => f(principal)(request))
    }
}

private def _superUser[A](action: String => Action[A]) = {
    play.api.mvc.Security.Authenticated(getSuperUser, onUnauthorized)(action)
}

任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:0)

对不起,我对此架构有点困惑:

  1. API调用在哪里?在模型内吗?您是在当前Play应用之外拨打电话吗?您为什么不使用Future API?因为那样您可以recover。这样可以帮助您进行日志记录和错误处理。
  2. all方法获取请求,然后它不返回HTTP响应。您为什么不传递请求中的需求(例如Cookie)。
  3. 我认为,您的问题的答案是将您的行动构成与行动结合起来。像这样:

    def myMethod(queryParam: String) = myDefinedAction compose Action { ??? } 
    
    //In case you want to use the Future API, then you need to be async
    def myMethod(queryParam: String) = (myDefinedAction compose Action).async {
      implicit request => 
         apiCall.map{
           case _ => Ok("good request") 
         }.recover{case _ => BadRequest} 
    
    }