自定义 Akka HTTP 指令以异步映射响应
Custom Akka HTTP directive to async map response
我正在尝试构建一个自定义 Akka HTTP 指令,将响应异步映射到另一个。给定以下定义:
trait ResponseFilter {
def apply(request: HttpRequest, response: HttpResponse): Future[HttpResponse]
}
我想构建一个类似于此的指令(无法编译):
def filterResponse(responseFilter: ResponseFilter): Directive0 = {
extractRequest { request =>
mapResponse { response =>
responseFilter(request, response)
}
}
}
编译错误为:
...type mismatch;
[error] found : scala.concurrent.Future[akka.http.scaladsl.model.HttpResponse]
[error] required: akka.http.scaladsl.model.HttpResponse
[error] responseFilter(request, response)
[error] ^
[error] one error found
这是有道理的,因为 mapResponse
是同步的。
我知道 onSuccess
但它似乎没有帮助。
我花了一些时间研究 Akka HTTP 源代码,并提出了以下似乎按预期工作的解决方案:
def filterResponse(responseFilter: ResponseFilter): Directive0 = {
Directive { inner => ctx =>
implicit val ec = ctx.executionContext
inner(())(ctx).flatMap {
case result: Complete =>
responseFilter(ctx.request, result.response).map { filteredResponse =>
RouteResult.Complete(filteredResponse)
}
case incomplete => Future.successful(incomplete)
}
}
}
如果有更好的方法,请告诉我!
我正在尝试构建一个自定义 Akka HTTP 指令,将响应异步映射到另一个。给定以下定义:
trait ResponseFilter {
def apply(request: HttpRequest, response: HttpResponse): Future[HttpResponse]
}
我想构建一个类似于此的指令(无法编译):
def filterResponse(responseFilter: ResponseFilter): Directive0 = {
extractRequest { request =>
mapResponse { response =>
responseFilter(request, response)
}
}
}
编译错误为:
...type mismatch;
[error] found : scala.concurrent.Future[akka.http.scaladsl.model.HttpResponse]
[error] required: akka.http.scaladsl.model.HttpResponse
[error] responseFilter(request, response)
[error] ^
[error] one error found
这是有道理的,因为 mapResponse
是同步的。
我知道 onSuccess
但它似乎没有帮助。
我花了一些时间研究 Akka HTTP 源代码,并提出了以下似乎按预期工作的解决方案:
def filterResponse(responseFilter: ResponseFilter): Directive0 = {
Directive { inner => ctx =>
implicit val ec = ctx.executionContext
inner(())(ctx).flatMap {
case result: Complete =>
responseFilter(ctx.request, result.response).map { filteredResponse =>
RouteResult.Complete(filteredResponse)
}
case incomplete => Future.successful(incomplete)
}
}
}
如果有更好的方法,请告诉我!