简体   繁体   English

基本的Akka HTTP客户端帖子不起作用

[英]Basic akka http client post not working

I am trying to make a basic http client posting some data to a REST API with Akka HTTP but I cannot make the following code work : 我正在尝试使一个基本的http客户端使用Akka HTTP将一些数据发布到REST API,但无法使以下代码正常工作:

def sendData(e : GenericEvent): Future[Either[(String,StatusCode),(GenericEvent,StatusCode)]] = {

val request = Marshal(e).to[RequestEntity]
val responseFuture: Future[HttpResponse] = request map { req =>
  Source.single(HttpRequest(method = HttpMethods.POST, uri = s"/data-ingest", headers = List(auth), entity = req))
    .via(dataIngestFlow)
    .runWith(Sink.head)
}

responseFuture.flatMap { response =>
  response.status match {
    case OK => Unmarshal(response.entity).to[GenericEvent].map(Right(_, response.status))
    case BadRequest => Future.successful(Left(s"$e.data: incorrect data", response.status))
    case _ => Unmarshal(response.entity).to[String].flatMap { entity =>
      val error = s"generic event ingest failed with status code ${response.status} and entity $entity"
      logger.error(error)
      Future.failed(new IOException(error))
    }
  }
}

I got the following error 我收到以下错误

polymorphic expression cannot be instantiated to expected type;
[error]  found   :      
[T]akka.stream.scaladsl.Sink[T,scala.concurrent.Future[T]]
[error]  required:         
akka.stream.Graph[akka.stream.SinkShape[akka.http.scaladsl.model.HttpResponse],akka.http.scaladsl.model.HttpResponse]
[error]         .runWith(Sink.head)

Here is the code for the dataIngestFlow 这是dataIngestFlow的代码

val dataIngestFlow = Http().outgoingConnection(config.endpointUrl,config.endpointPort)

Here is the code on server side : 这是服务器端的代码:

val routes = {
    logRequestResult("akka-http-microservice") {
      path("event-ingest") {
        post {
          entity(as[GenericEvent]) { eventIngest =>
            log.info(s"Ingesting {} and publishing event to Kafka topic {}.", eventIngest.eventType,config.kafkaTopic)
            kafka ! eventIngest
            complete {
              eventIngest
            }
          }~
            entity(as[List[GenericEvent]]) { eventIngestList =>
              eventIngestList.foreach{ eventIngest=>
                log.info(s"Ingesting {} and publishing event List to Kafka topic {}.", eventIngest.eventType,config.kafkaTopic)
                kafka ! eventIngest
              }
              complete {
                eventIngestList
              }
            }
        }
      }
    }
  }

I tried another simple client, it builds well but the ingestion stop after 160 events, the server doesn't receive anymore events. 我尝试了另一个简单的客户端,该客户端构建良好,但是在160个事件之后摄取停止,服务器不再接收任何事件。

The first problem I see with your example is that RequestEntity does not have a map function. 我在您的示例中看到的第一个问题是RequestEntity没有映射功能。 Therefore, the following line 因此,以下行

val responseFuture: Future[HttpResponse] = request map { ...

should not compile. 不应该编译。

Further, if request is actually a Future (which I infer from the map) then responseFuture is actually of type Future[Future[HttpResponse]] because the stream materializes into its own Future. 此外,如果request实际上是一个Future(我从地图上推断出),则responseFuture实际上是Future[Future[HttpResponse]]因为该流具体化为它自己的Future。 To solve this problem you can use Future.flatMap instead of map. 要解决此问题,可以使用Future.flatMap代替map。 Namely: 即:

val responseFuture: Future[HttpResponse] = request flatMap { req =>

This is the monadic bind operation within Futures. 这是期货中的单价绑定操作

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

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