首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >akka ` `HttpResponse`‘as Argonaut ` `Json`’

akka ` `HttpResponse`‘as Argonaut ` `Json`’
EN

Stack Overflow用户
提问于 2016-12-04 14:18:12
回答 2查看 437关注 0票数 0

我试图将akka HttpResponse编组如下:

代码语言:javascript
复制
{
  "code": 200,
  "headers": [],
  "body": "{\"data\": \"Yes!\"}"
}

如果我为这个实例编写了一个Argonaut EncodeJson,它可能如下所示:

代码语言:javascript
复制
implicit def httpResponseEncodeJson: EncodeJson[HttpResponse] =
  EncodeJson(
    (res: HttpResponse) ⇒ {
      ("code" := res._1.value) ->:
      ("headers" := res._2.toList) ->:
      ("body" := res._3) ->: jEmptyObject
    }
  )

我已经设法将头封封为json。唯一的问题是身体,即ResponseEntity。因为它是一个akka流,所以如果我使用.toStrict,它只能返回一个未来。

有人能指导我怎么整理它吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-01-19 14:32:49

如果可能,我将将封送值保留为Future,以保持实体提取的异步性。

我一开始就有这样的想法

代码语言:javascript
复制
  case class StrictHttpResponse(code: String, headers: List[HttpHeader], body: String)

  def toStrictResponse(response: HttpResponse): Future[StrictHttpResponse] = response.entity.dataBytes.runFold(ByteString(""))(_ ++ _).map { bs =>
    StrictHttpResponse(response.status.value, response.headers.toList, bs.utf8String)
  }

  implicit def httpResponseEncodeJson: EncodeJson[StrictHttpResponse] =
    EncodeJson(
      (res: StrictHttpResponse) ⇒ {
        ("code" := res.code) ->:
          ("headers" := res.headers) ->:
          ("body" := res.body) ->: jEmptyObject
      }
    )

  def encodeResponse(response: HttpResponse): Future[Json] = toStrictResponse(response).map(_.jencode)

然后--例如--通过提供回调来处理encodeResponse的结果。

票数 0
EN

Stack Overflow用户

发布于 2017-01-20 15:17:50

我最终使用了这个:

代码语言:javascript
复制
  implicit def httpResponseListMarshal: ToEntityMarshaller[List[HttpResponse]] =
Marshaller { implicit ec ⇒ (responses: List[HttpResponse]) ⇒

    // Sink for folding Source of ByteString into 1 single huge ByteString
    val sink = Sink.fold[ByteString, ByteString](ByteString.empty)(_ ++ _)

    // A List of Future Json obtained by folding Source[ByteString]
    // and mapping appropriately
    val listFuture: List[Future[Json]] = for {
      res ← responses
    } yield for {
      byteString ← res._3.dataBytes runWith sink
      string = byteString.utf8String
    } yield ("code" := res._1.intValue) ->:
      ("headers" := res._2.toList) ->:
      ("body" := string) ->: jEmptyObject


    // Convert List[Future[Json]] to Future[List[Json]]
    val futureList: Future[List[Json]] = Future.sequence(listFuture)

    // ToEntityMarshaller is essentially a   Future[List[Marshalling[RequestEntity]]]
    for {
      list ← futureList
      json = jArray(list).nospaces
    } yield List(
      Marshalling.Opaque[RequestEntity](() ⇒
        HttpEntity(`application/json`, json)
    ).asInstanceOf[Marshalling[RequestEntity]]
  )
}

完整的代码和示例用法可以在这里找到:https://github.com/yashsriv/akka-http-batch-api/blob/argonaut/src/main/scala/org.yashsriv/json/Batch.scala

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/40959541

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档