使用迭代器完成akka-http响应

时间:2018-06-13 13:20:30

标签: scala serialization akka-http

我有mongodb查询结果的迭代器,我想将这些结果流式传输到http响应,而不将整个结果集加载到内存中。

是否可以使用迭代器而不是集合或未来完成akka http响应?

2 个答案:

答案 0 :(得分:2)

给出Iterator数据:

type Data = ???

val dataIterator : () => Iterator[Data] = ???

您首先需要一个功能来将Data转换为ByteString表示形式,以及表示形式的ContentTypee.g. json, binary, csv, xml, ...):

import akka.util.ByteString
import akka.http.scaladsl.model.ContentType    

val dataToByteStr : Data => ByteString = ???

//see akka.http.scaladsl.model.ContentTypes for possible values
val contentType : ContentType = ???

现在可以使用Iterator和转换器函数创建一个HttpResponse,它将结果流回http客户端,而不会将整个数据集保存在内存中:

import akka.http.scaladsl.model.HttpEntity.{Chunked, ChunkStreamPart}
import akka.http.scaladsl.model.ResponseEntity    
import akka.stream.scaladsl.Source
import akka.http.scaladsl.model.HttpResponse

val chunks : Source[ChunkStreamPart,_] = 
  Source.fromIterator(dataIterator)
        .map(dataToByteStr)
        .map(ChunkStreamPart.apply)

val entity : ResponseEntity = Chunked.fromData(contentType, chunks)

val httpResponse : HttpResponse = HttpResponse(entity=entity)

注意:由于每次从dataIterator生成一个新的迭代器,您不必为每个传入请求创建新的httpResponse;所有请求都可以使用相同的响应。

答案 1 :(得分:0)

看看Alpakka MongoDB connector。它允许从Mongo集合创建一个Source,如:

val source: Source[Document, NotUsed] = MongoSource(numbersColl.find())

val rows: Future[Seq[Document]] = source.runWith(Sink.seq)

或者您可能希望将自己的源实现作为GraphStage。