如何使用 Stream 和 Custom Status Code 完成 Akka Http 响应
How to complete Akka Http response with Stream and Custom Status Code
我有一个使用 akka-streams 进行数据处理的 akka-http 应用程序。因此,使用 Source[Result, _]
完成请求以免费获得跨 HTTP 边界的背压是有意义的。
版本:
- akka-http 10.0.7
- akka-streams 2.5.2
- 阿卡 2.5.2
这是代码的简化版本,它工作得很好。
pathEnd { post { entity(asSourceOf[Request]) { _ =>
complete {
Source.single("ok")
}
}}}
因为这个 enpoint 应该创建和实体,而不是 returning 200 OK 给请求者我想 return 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 可能是实现该目标的一种方法,但这基本上意味着我将需要每个端点一个解组器,这不太方便或不清楚。
所以,问题是,是否有一种(比自定义解组器更方便)的方法来使用 Source[_,_]
完成请求,同时还提供状态代码。
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)
}
我遇到了这个问题并采取了使用 mapResponse 覆盖状态代码的方法。这是我找到的最简单的方法。
mapResponse(_.copy(status = StatusCodes.Accepted)) {
complete {
Source.single("ok")
}
}
Ramon 的回答的缺点是您要负责编组流(到 ByteString)和内容协商。
我有一个使用 akka-streams 进行数据处理的 akka-http 应用程序。因此,使用 Source[Result, _]
完成请求以免费获得跨 HTTP 边界的背压是有意义的。
版本:
- akka-http 10.0.7
- akka-streams 2.5.2
- 阿卡 2.5.2
这是代码的简化版本,它工作得很好。
pathEnd { post { entity(asSourceOf[Request]) { _ =>
complete {
Source.single("ok")
}
}}}
因为这个 enpoint 应该创建和实体,而不是 returning 200 OK 给请求者我想 return 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 可能是实现该目标的一种方法,但这基本上意味着我将需要每个端点一个解组器,这不太方便或不清楚。
所以,问题是,是否有一种(比自定义解组器更方便)的方法来使用 Source[_,_]
完成请求,同时还提供状态代码。
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)
}
我遇到了这个问题并采取了使用 mapResponse 覆盖状态代码的方法。这是我找到的最简单的方法。
mapResponse(_.copy(status = StatusCodes.Accepted)) {
complete {
Source.single("ok")
}
}
Ramon 的回答的缺点是您要负责编组流(到 ByteString)和内容协商。