使用akka-http和mongo-scala-driver

时间:2017-03-10 23:11:33

标签: mongodb scala akka future akka-http

我想使用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)

2 个答案:

答案 0 :(得分:1)

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

complete(feature.map(_.toJson))

答案 1 :(得分:0)

首先,您不应在收到的每个请求中创建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与期货配合得很好,这可以不用阻止你的应用程序。