简体   繁体   English

使用akka-http和mongo-scala驱动程序

[英]Work with akka-http and mongo-scala-driver

I want to use akka-http and new mongo-scala-driver for my rest service. 我想为我的休息服务使用akka-http和新的mongo-scala-driver

This code is working 该代码有效

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()))
      }
    }
  }
}

But I want to remove the blocking code Await.result and write asynchronous. 但是我想删除阻塞代码Await.result并编写异步代码。

How can I do it? 我该怎么做? Thanks 谢谢

build.sbt: 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"

UPDATE 更新

If I change my code: 如果我更改代码:

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

I get an error: 我收到一个错误:

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

UPDATE 更新

If I change my code: 如果我更改代码:

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

I get en error: 我得到错误:

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)

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

complete(feature.map(_.toJson))

First of all, you should not create a MongoClient instance in every request you receive. 首先,您不应在收到的每个请求中创建MongoClient实例。 Also, you should not block your request to get the response. 另外,您不应阻止获取响应的请求。 The Await.result(f, duration) will block the default dispatcher and probably decrease the performance of your application drastically. 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")
          }
        }
      }
    }
  }
}

That's more likely what you're looking for. 这更可能是您要寻找的东西。 Akka HTTP works very well with Futures and this is way to go without blocking your app. Akka HTTP与Futures配合得很好,这是不阻塞应用程序的一种方式。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM