【问题标题】:Work with akka-http and mongo-scala-driver使用 akka-http 和 mongo-scala-driver
【发布时间】:2017-08-01 10:32:48
【问题描述】:

我想使用akka-http 和新的mongo-scala-driver 进行休息服务。

此代码有效

val routes = {
  pathPrefix("info") {
    pathEndOrSingleSlash {
      get {
        val mongoClient: MongoClient = MongoClient("mongodb://localhost:27017,localhost:27018,localhost:27019/?replicaSet=rs0")
        val database: MongoDatabase = mongoClient.getDatabase("test")
        val collection: MongoCollection[Document] = database.getCollection("test")
        val future  = collection.find().limit(10).toFuture()
        val list = Await.result(future, Duration(10, TimeUnit.SECONDS))
        complete(list.map(_.toJson()))
      }
    }
  }
}

但是我想去掉阻塞代码Await.result,写异步。

我该怎么做?谢谢

build.sbt:

scalaVersion := "2.12.1"

"org.mongodb.scala" %% "mongo-scala-driver" % "1.2.1"
"com.typesafe.akka" %% "akka-http-core" % "10.0.4"
"com.typesafe.akka" %% "akka-http" % "10.0.4"

更新

如果我更改代码:

complete(future.map(_.toJson()))

我收到一个错误:

Error:(160, 36) value toJson is not a member of Seq[org.mongodb.scala.Document]
        complete(future.map(_.toJson()))

更新

如果我更改代码:

        onComplete(future) {
          case Success(value) => complete(value)
          case Failure(ex)    => complete((InternalServerError, s"An error occurred: ${ex.getMessage}"))
        }

我得到一个错误:

Error:(166, 47) type mismatch;
found   : Seq[org.mongodb.scala.bson.collection.immutable.Document]
required: akka.http.scaladsl.marshalling.ToResponseMarshallable
          case Success(value) => complete(value)

【问题讨论】:

标签: mongodb scala akka future akka-http


【解决方案1】:

假设功能是未来,只需删除等待并执行:

complete(feature.map(_.toJson))

【讨论】:

  • 如果我更改我的代码,我得到一个错误:错误:(160, 36) value toJson is not a member of Seq[org.mongodb.scala.Document] complete(future.map(_ .toJson()))
  • @bobinshtein 您的主要问题是您没有提供编组器。有必要将数据类型转换为“有线格式”,即您可以将其放入请求中。
  • 好吧,这是解组器的问题,但我不明白我怎么写这个。
  • 我想你可能需要一个额外的map:complete(future.map(_.map(_.toJson))。一个map 用于未来,一个map 用于列表。
【解决方案2】:

首先,您不应该在收到的每个请求中都创建 MongoClient 实例。 此外,您不应该阻止您获取响应的请求。 Await.result(f, duration) 将阻止默认调度程序,并可能大幅降低应用程序的性能。

//other imports
import akka.http.scaladsl.server.Directives._
import akka.http.scaladsl.model.StatusCodes._

object Endpoint {
  val mongoClient: MongoClient = MongoClient("mongodb://localhost:27017,localhost:27018,localhost:27019/?replicaSet=rs0")
  val database: MongoDatabase = mongoClient.getDatabase("test")
  val collection: MongoCollection[Document] = database.getCollection("test")

  val routes = {
    pathPrefix("info") {
      pathEndOrSingleSlash {
        get {
          val future  = collection.find().limit(10).toFuture()
          onComplete(future) {
            case Success(list) =>
              complete(OK -> list.map(_.asJson()))
            case Failure(e) =>
              log.error(e)
              complete(InternalServerError -> "an error occurred while performing the request")
          }
        }
      }
    }
  }
}

这更有可能是您正在寻找的。 Akka HTTP 与 Futures 配合得非常好,这是一种不会阻塞您的应用程序的方法。

【讨论】:

    猜你喜欢
    • 2019-11-12
    • 2016-07-04
    • 2021-11-12
    • 2017-10-03
    • 1970-01-01
    • 2017-10-17
    • 1970-01-01
    • 2017-03-20
    • 2020-02-07
    相关资源
    最近更新 更多