Akka HTTP使用响应unmarshaller

时间:2017-05-10 14:58:15

标签: java akka-http akka-stream

我正在使用Akka流和Akka HTTP构建数据管道。用例非常简单,接收来自用户的Web请求,该请求将执行两项操作。首先通过调用第三方API创建会话,然后将此会话提交到某个持久存储,当我们收到会话时,它将代理原始用户请求但添加会话数据。

我已经开始处理数据管道的第一个分支,即会话处理,但我想知道是否有更优雅的方法将第3方API的HTTP响应解组为当前我正在使用的POJO Jackson.unmarshaller.unmarshal返回CompletionStage<T>,然后我必须将其展开到T。它不是很优雅,我猜测Akka HTTP有更聪明的方法来做到这一点。

这是我现在的代码

private final Source<Session, NotUsed> session =
        Source.fromCompletionStage(
                getHttp().singleRequest(getSessionRequest(), getMat())).
                map(r -> Jackson.unmarshaller(Session.class).unmarshal(r.entity(), getMat())).
                map(f -> f.toCompletableFuture().get()).
                alsoTo(storeSession);

1 个答案:

答案 0 :(得分:1)

Akka Streams为您提供mapAsync,这是一个以可配置的非阻塞方式处理管道中异步计算的阶段。

您的代码应该变成

Source.fromCompletionStage(
                getHttp().singleRequest(getSessionRequest(), getMat())).
                mapAsync(4, r -> Jackson.unmarshaller(Session.class).unmarshal(r.entity(), getMat())).
                alsoTo(storeSession);

请注意:

  1. 在这种情况下,这不仅仅是优雅的问题,因为CompletableFuture.get是一个阻止呼叫。这可能会在您的管道中造成可怕的问题。
  2. Int所需的mapAsync参数(并行性)允许微调同时运行多少并行异步操作。
  3. mapAsync中可以找到<a th:href="@{/user/map(userId=${user.id},mapId=${map.id})}"> 中的更多信息。