如何使用Stream和Custom Status Code完成Akka Http响应

时间:2017-07-06 03:39:51

标签: scala http-status-codes akka-stream akka-http

我有一个使用akka-streams进行数据处理的akka​​-http应用程序。因此,使用Source[Result, _]完成请求以获得免费的HTTP边界背压是有道理的。

版本:

  • akka-http 10.0.7
  • akka-streams 2.5.2
  • akka 2.5.2

这是代码的简化版本,它运行得很好。

pathEnd { post { entity(asSourceOf[Request]) { _ =>
    complete {
        Source.single("ok")
    }
}}}

由于这个enpoint应该创建和实体,而不是向请求者返回200 OK,我想返回204 CREATED状态代码。但是,我无法找到办法:

  • complete { Created -> source.single("ok") }无法使用Type mismatch, expected: ToResponseMarshallable, actual: (StatusCodes.Success, Source[String, NotUsed])
  • 进行编译
  • complete { source.single((Created, "ok")) }Type mismatch, expected: ToResponseMarshallable, actual: Source[(StatusCodes.Success, String), NotUsed]
  • 失败
  • complete(Created) { Source.single("ok") }Type mismatch, expected: RequestContext, actual: Source[String,NotUsed]
  • 失败
  • complete(Created, Source.signle("ok")too many arguments for method complete(m: => ToResponseMarshallable)
  • 失败

看起来custom marshaller可能是实现这一目标的一种方式,但它基本上意味着每个端点需要一个unmarshaller,这不太方便或不清楚。

所以,问题是,是否有一种(比自定义unmarshaller更方便)的方式来完成Source[_,_]请求,同时还提供状态代码。

2 个答案:

答案 0 :(得分:1)

来自the documentation

complete(Created -> "bar")

如果您想提供一些Source数据,请构建HttpResponse并将其传递给complete

import akka.http.scaladsl.model.HttpEntity.Chunked
import akka.http.scaladsl.model.ContentTypes
import akka.http.scaladsl.model.HttpEntity.ChunkStreamPart

complete {

  val entity = 
    Chunked(ContentTypes.`text/plain(UTF-8)`,
            Source.single("ok").map(ChunkStreamPart.apply))

  HttpResponse(status = Created, entity=entity)
}

答案 1 :(得分:1)

我遇到了这个问题并采用了mapResponse来覆盖状态代码。这是我发现的最简单的方法。

mapResponse(_.copy(status = StatusCodes.Accepted)) {
  complete {
    Source.single("ok")
  }
}      

Ramon的答案的缺点是你负责编组流(到ByteString)和内容协商。