I'm trying to marshal an akka HttpResponse
as such:
{
"code": 200,
"headers": [],
"body": "{\"data\": \"Yes!\"}"
}
If I write an Argonaut EncodeJson
for this Instance, it might look like this:
implicit def httpResponseEncodeJson: EncodeJson[HttpResponse] =
EncodeJson(
(res: HttpResponse) ⇒ {
("code" := res._1.value) ->:
("headers" := res._2.toList) ->:
("body" := res._3) ->: jEmptyObject
}
)
I have managed to marshal the headers as json. The only problem is with the body, i.e.,
the ResponseEntity
. Since it is an akka stream, it can only return a future, if I use .toStrict
.
Can anybody guide me as to how I might marshal it?
If possible, I would keep the marshalled value as a Future
, to preserve the asynchrony of the entity extraction.
I would start by having something along the lines of
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)
and then - e.g. - handle the result of encodeResponse
by providing a callback.