J'ai un point final que nous pouvons appeler /test
qui récupère en interne les données d'une API tierceet veut ensuite faire une transformation avant de retourner une réponse. Lorsque je suis suspendu, cette API tierce retourne un fichier JSON compressé et je ne peux pas le décoder (pour le moment). J'ai trouvé le directive decodeRequest mais il semble que je dois utiliser cela dans mon routage et je suis un niveau plus profond ici. J'ai une méthode interne que j'appelle une fois que je reçois un GET
à mon point final /test
qui est nommé do3rdPartyAPIRequest
où je construis un HttpRequest
et passer à Http().singleRequest()
alors en retour j'ai un Future[HttpResponse]
qui est où je pense que je veux être mais je suis coincé ici.
Avec certaines API locales que j’ai construites et consommées de la même manière, je n’ai pas encodé mes réponses de manière typique. Future[HttpResponse]
Je vérifie l'état de la réponse et passe à la conversion en JSON via Unmarshal
mais celui-ci nécessite une étape supplémentaire à ma connaissance avant de passer à JSON. Je me rends compte que cette question est très similaire à celui-là Cependant, cela est spécifique à la pulvérisation et je n'ai pas été en mesure de traduire cette réponse en http: akka
Réponses:
6 pour la réponse № 1Enfin compris cela - ce n'est peut-être pas le meilleur moyen d'obtenir un bytestring de la réponse, mais cela fonctionne .. Il s'avère que vous pouvez utiliser Classe Gzip
et vous avez deux options
Gzip.decode
Gzip.decoderFlow
Voici mes exemples au cas où cela vous aiderait:
def getMyDomainObject(resp: HttpResponse):Future[MyDomain] = {
for {
byteString <- resp.entity.dataBytes.runFold(ByteString(""))(_ ++ _)
decompressedBytes <- Gzip.decode(byteString)
result <- Unmarshal(decompressedBytes).to[MyDomain]
} yield result
}
def getMyDomainObjectVersion2(resp:HttpResponse):Future[MyDomain] = {
resp.entity.dataBytes
.via(Gzip.decoderFlow)
.runWith(Sink.head)
.flatMap(Unmarshal(_).to[MyDomain])
}
2 pour la réponse № 2
Vous vous attendriez à ce que le contenu compressé soit géré par défaut par akka-http, mais il ne fournit que PredefinedFromEntityUnmarshallers
et à l'intérieur de l'entité il n'y a pas d'informations sur Content-encoding
entête.
Pour résoudre ce problème, vous devez implémenter votre propre Unmarshaller et en tenir compte.
Exemple:
implicit val gzipMessageUnmarshaller = Unmarshaller(ec => {
(msg: HttpMessage) => {
val `content-encoding` = msg.getHeader("Content-Encoding")
if (`content-encoding`.isPresent && `content-encoding`.get().value() == "gzip") {
val decompressedResponse = msg.entity.transformDataBytes(Gzip.decoderFlow)
Unmarshal(decompressedResponse).to[String]
} else {
Unmarshal(msg).to[String]
}
}
})