我们正在使用Kafka,并希望使用interactive queries来访问状态存储中的数据。我们已有一个使用Akka HTTP来提供REST API的服务,并且我们希望将交互式查询集成到流中。
kafka-streams-query似乎是最合适的选择。但是,它通过公开使用低级API的route
属性(它映射到Flow[HttpRequest, HttpResponse, Any]
)而集成到Akka HTTP中。我们之前的所有代码都使用Akka HTTP的路由DSL将代码连接起来。
我希望像下面这样的代码能够正常工作,但不会:
implicit val system:ActorSystem = ActorSystem("web")
implicit val materializer:ActorMaterializer = ActorMaterializer()
implicit val ec = system.dispatcher
val firstRoutes:Route = ... //a route object populated
val lastRoutes:Route = ... //other route object populad
val iqServiceFlow:Flow[HttpRequest, HttpResponse, Any] = ...// code that returns the interactive query service
val firstFlow = Route.handlerFlow(firstRoutes)
val lastFlow = Route.handlerFlow(lastRoutes)
// The following code doesn't work though everything I've seen online suggests it should
val handler = firstFlow via iqServiceFlow via lastFlow
Http().bindAndHandle(handler, "0.0.0.0", 8000)
如何在Akka流中合并流?
修改: 更正了处理程序分配语句。
答案 0 :(得分:3)
为清楚起见,让我们首先明确所有返回类型:
val iqServiceFlow: Flow[HttpRequest, HttpResponse, Any] = ...
val firstFlow: Flow[HttpRequest, HttpResponse, NotUsed] = Route.handlerFlow(firstRoutes)
val lastFlow: Flow[HttpRequest, HttpResponse, NotUsed] = Route.handlerFlow(lastRoutes)
此外,代替...
val handler = firstRoutes via iqServiceFlow via lastFlow
...您可能是说:
val handler = firstFlow via iqServiceFlow via lastFlow
为了将流与via
链接在一起,输入和输出类型必须匹配:即,第一个流的输出类型必须与第二个流的输入类型相同,依此类推。您要对处理程序执行的操作如下:
[HttpRequest, HttpResponse] // firstFlow
|
v
[HttpRequest, HttpResponse] // iqServiceFlow
|
v
[HttpRequest, HttpResponse] // lastFlow
所有流的输出类型为HttpResponse
,但它们各自的输入类型均为HttpRequest
,因此无法将它们与via
链接在一起。
要链接流,您需要一个函数以某种方式将HttpResponse
转换为HttpRequest
:
val respToReq: HttpResponse => HttpRequest = ...
您可以通过上述功能创建流程:
val convertingFlow: Flow[HttpResponse, HttpRequest] = Flow.fromFunction(respToReq)
现在您可以链接流程了:
val handler = firstFlow via convertingFlow via iqServiceFlow via convertingFlow via lastFlow
类型对齐如下:
[HttpRequest, HttpResponse] // firstFlow
|
v
[HttpResponse, HttpRequest] // convertingFlow
|
v
[HttpRequest, HttpResponse] // iqServiceFlow
|
v
[HttpResponse, HttpRequest] // convertingFlow
|
v
[HttpRequest, HttpResponse] // lastFlow
以上假设您可以重复使用相同的转换函数/流。如果这种假设不成立,您显然可以创建不同的转换函数/流。