有人可以解释这段代码是如何执行的吗?

Could someone explain how is the this code executing?

createUser 或 updateUser 如何使用 unmarshalValueJs 函数和传递参数。

    package controllers.user

import play.api._
import play.api.mvc._
import play.api.libs.json._
import play.api.libs.json.Reads._
import play.api.libs.functional.syntax._
import services.user.UserServiceComponent
import domain.user.User

trait UserController extends Controller {
    self: UserServiceComponent =>0

def emailAlreadyExists(implicit reads: Reads[String]) =
    Reads[String](js => reads.reads(js).flatMap { e =>
      userService.tryFindByEmail(e).map(_ => JsError("error.custom.emailAlreadyExists")).getOrElse(JsSuccess(e))
    })

implicit val userReads = (__ \ "email").read[String](email andKeep emailAlreadyExists)
                                       .map(resource => UserResource(resource))

implicit val userWrites = new Writes[User] {
    override def writes(user: User): JsValue = {
        Json.obj(
            "id" -> user.id,
            "email" -> user.email
        )
    }
}

什么 create User 传递给 unmarshalJsValue? 资源从哪里来?

def createUser = Action(parse.json) {request =>
    unmarshalJsValue(request) { resource: UserResource =>
        val user = User(Option.empty, resource.email)
        userService.createUser(user)
        Created
    }
}

def updateUser(id: Long) = Action(parse.json) {request =>
    unmarshalJsValue(request) { resource: UserResource =>
        val user = User(Option(id), resource.email)
        userService.updateUser(user)
        NoContent
    }
}

def findUserById(id: Long) = Action {
    val user = userService.tryFindById(id)
    if (user.isDefined) {
        Ok(Json.toJson(user))
    } else {
        NotFound
    }
}

def deleteUser(id: Long) = Action {
    userService.delete(id)
    NoContent
}

这里的R是什么? 将什么传递回 createUser?

    def unmarshalJsValue[R](request: Request[JsValue])(block: R => Result)(implicit rds : Reads[R]): Result =
        request.body.validate[R](rds).fold(
            valid = block,
            invalid = e => {
                val error = e.mkString
                Logger.error(error)
                BadRequest(error)
            }
        )

}

case class UserResource(email: String)

R 是类型变量。定义 def unmarshalJsValue[R](request: Request[JsValue])(block: R => Result)(implicit rds : Reads[R]) 为:

  • 我是一个叫unmarshallJsValue的方法。

  • 我需要一个可能是任何类型的参数。

  • 我需要 Request[JsValue] 的值(大概是 JSON 实体中包含的请求)。

  • 我需要一个函数,给定类型 R 的某个值,生成 Result.

  • 我需要一个值在 implicit 范围内,即类型 RReads。换句话说,我需要一种方法将 JsValue 转换为 R,无论 R 可能是什么。 (如果您查看 the docs for Reads,您会注意到它的唯一方法 reads 具有此效果。)

总而言之,整个函数只是说,给我一些代码块,它从一些我知道如何转换为 JSON 的数据中生成 Result。函数体只是尝试将 JSON 转换为所需的类型(称为 unmarshalling)。如果成功,它将运行该块。否则,您会收到 BadRequest 客户端错误。

编译器无法知道客户端在现实生活中提供的 JSON 是否可以转换为某种类型 R,但它可能需要一个 JSON - > R 转换器,以及一些错误处理代码(如果在实际数据上失败)。