基本的Create-from-Json方法演练

时间:2016-03-14 21:28:27

标签: scala reactivemongo play-reactivemongo

我是Play,scala和reactivemongo的新手,并且想知道是否有人可以用简单的术语向我解释以下代码。

def createFromJson = Action.async(parse.json) { request =>
import play.api.libs.json.Reads._

val transformer: Reads[JsObject] =
  Reads.jsPickBranch[JsString](__ \ "name") and
    Reads.jsPickBranch[JsNumber](__ \ "age") and
    Reads.jsPut(__ \ "created", JsNumber(new java.util.Date().getTime())) reduce

request.body.transform(transformer).map { result =>
  collection.insert(result).map { lastError =>
    Logger.debug(s"Successfully inserted with LastError: $lastError")
    Created
  }
}.getOrElse(Future.successful(BadRequest("invalid json")))}

我知道它会从具有名称和年龄属性的JSON用户创建用户。我不明白的是在这种方法中读取输入JSON的方式。还有Action.async(par.json)的概念,request => getorElse,Future等。

也非常感谢任何更容易/更简单的方法来编写这种方法。

提前致谢!

1 个答案:

答案 0 :(得分:2)

我相信你在我按照优秀的反应性mongo文档制作的模板中找到了这段代码。

我觉得有点不得不解释它。让我们来看看代码。

def createFromJson = Action.async(parse.json) { request =>

函数createFromJson将返回一个异步(返回结果的未来)的Action(播放内容),它处理json格式的主体。为此,它将使用该请求。

文档: https://www.playframework.com/documentation/2.5.x/ScalaAsync

json可以是遵循json格式的任何东西,例如数组String,对象,......

我们的变换器只会从json中获取我们感兴趣的数据并返回一个干净的json对象

val transformer: Reads[JsObject] =
  Reads.jsPickBranch[JsString](__ \ "name") and
    Reads.jsPickBranch[JsNumber](__ \ "age") and
    Reads.jsPut(__ \ "created", JsNumber(new java.util.Date().getTime())) reduce

如您所见,它会选择分支名称作为字符串,分支 age 作为数字。它还会在创建时将一个字段创建添加到最终的json对象中。

如您所见,我们没有将它转换为Person实例,它只是一个JsObject实例,因为它在

中定义
val transformer: Reads[JsObject] ....

Play为您提供了一些以更简单的方式处理json的方法。这个例子试图展示直接操纵json值而不转换为模型的能力。 例如,如果您有案例类

case class Person(name: String, age: Int)

您可以自动创建一个读取

val personReads: Person[Person] = Json.reads[Person]

但是要将它存储在Mongo中 DB没有理由构建此实例,然后再将其转换为json。 当然,如果您需要在插入模型之前对模型执行某些逻辑,则可能需要创建模型。

文档:

考虑到这一点,其余的代码应该是明确的

request.body.transform(transformer).map { result =>
  collection.insert(result).map { lastError =>
    Logger.debug(s"Successfully inserted with LastError: $lastError")
    Created
  }
}

从请求中,我们将body(一个JsValue)转换为JsObject(结果),然后将其插入到集合中。 Insert返回带有最后一个错误的Future,当存储Person时,将记录最后一个错误,并将一个Created(201代码)返回给API的客户端。

现在也应该清楚最后一点

}.getOrElse(Future.successful(BadRequest("invalid json")))

如果将请求的json主体解析并转换为我们的JsObject有任何问题,那么结果为BadRequest(400代码)的已完成的未来将返回给客户端。 这是一个未来,因为Action.Async需要将结果的未来作为返回类型。

享受scala。