Unmarshall gzipped responses
jhoncamargo opened this issue · 3 comments
Hi everyone, using this directive in routes
encodeResponseWith(Gzip) {
...
}
produce this error:
io.circe.ParsingFailure: expected json value got � (line 1, column 1)
when executing this line:
Unmarshal(httpResponse.entity).to[...]
This is because the response is encoded with gzip so it is an Array[Byte] and the Unmarshaller is expecting a ByteString
I could manage to overcome using this function to unzip the response:
/**
* Unzip and return the String-JSON representation in this Array[Byte]
*/
def unzip(compressed: Array[Byte]): Either[Throwable, String] =
Try {
val inputStream = new GZIPInputStream(new ByteArrayInputStream(compressed))
scala.io.Source.fromInputStream(inputStream).mkString
}.toEither
And defining this Unmarshaller:
implicit def circeCompressUnMarshaller[A](implicit decoder: Decoder[A]): FromEntityUnmarshaller[A] =
Unmarshaller.byteArrayUnmarshaller.map(
unzip(_).flatMap(jawn.decode[A]).fold(throw _, identity)
)
But I dont know if this is the right solution and it can be added to this repo.
Thank you @hseeberger
@jhoncamargo cool stuff: you know you Scala!
I think compression should not be a concern of this library which is only focussed on JSON. I also think that it's not a great idea to implicitly unzip stuff: that probably should happen explicitly.
Therefore I suggest to first wrap your route in a unzipping stage and then apply the usual unmarhalling magic. Does that make sense?
I didn't understand about the unzipping stage, my routes need to support Gzip compression so I can't remove that directive from them. Please can you provide some code example or links related to your suggestion?
Thank you
Never used that myself, sorry.